2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 ==================================================================================
20 Timer takes four parameters:
21 1) strId string 'string format timerMap key'
22 2) nbrId int 'numeric format timerMap key'
23 3) timerDuration time.Duration 'timer duration'
24 4) timerFunction func(string, int) 'function to be executed when timer expires'
26 Timer function is put inside in-build time.AfterFunc() Go function, where it is run inside own Go routine
27 when the timer expires. Timer are two key values. Both are used always, but the other one can be left
28 "empty", i.e. strId = "" or nbrId = 0. Fourth parameter, the timer function is bare function name without
29 any function parameters and parenthesis! Filling first parameter strId with related name can improve
30 code readability and robustness, even the numeric Id would be enough from functionality point of view.
32 TimerStart() function starts the timer. If TimerStart() function is called again with same key values
33 while earlier started timer is still in the timerMap, i.e. it has not been stopped or the timer has not
34 yet expired, the old timer is deleted and new timer is started with the given time value.
36 StopTimer() function stops the timer. There is no need to call StopTimer() function after the timer has
37 expired. Timer is removed automatically from the timeMap. Calling StopTimer() function with key values not
38 existing in the timerMap, has no effect.
40 NOTE: Each timer is run in separate Go routine. Therefore, the function that is executed when timer expires
41 MUST be designed to be able run concurrently! Also, function run order of simultaneously expired timers cannot
44 If you need to transport more information to the timer function, consider to use another map to store the
45 information with same key value, as the started timer.
47 Init timerMap example:
48 timerMap := new(TimerMap)
51 StartTimer() and StartTimer() function usage examples.
53 subReqTime := 2 * time.Second
55 timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, handleSubscriptionRequestTimer)
56 timerMap.StopTimer("RIC_SUB_REQ", int(subId))
59 subReqTime := 2 * time.Second
60 strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
61 timerMap.StartTimer(strId, 0, subReqTime, handleSubscriptionRequestTimer)
62 timerMap.StopTimer(strId, 0)
65 subReqTime := 2 * time.Second
66 strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
67 timerMap.StartTimer(RIC_SUB_REQ_" + strId, 0, subReqTime, handleSubscriptionRequestTimer)
68 timerMap.timerMap.StopTimer("RIC_SUB_REQ_" + strId, 0)
70 Timer function example. This is run if any of the above started timer expires.
71 func handleSubscriptionRequestTimer1(strId string, nbrId int) {
72 fmt.Printf("Subscription Request timer expired. Name: %v, SubId: %v\n",strId, nbrId)
79 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
84 type TimerKey struct {
89 type TimerInfo struct {
90 timerAddress *time.Timer
91 timerFunctionAddress func()
94 type TimerMap struct {
95 timer map[TimerKey]TimerInfo
99 // This method should run as a constructor
100 func (t *TimerMap) Init() {
101 t.timer = make(map[TimerKey]TimerInfo)
104 func (t *TimerMap) StartTimer(strId string, nbrId int, expireAfterTime time.Duration, timerFunction func(srtId string, nbrId int)) bool {
106 defer t.mutex.Unlock()
107 if timerFunction == nil {
108 xapp.Logger.Error("StartTimer() timerFunc == nil\n")
111 timerKey := TimerKey{strId, nbrId}
112 // Stop timer if there is already timer running with the same id
113 if val, ok := t.timer[timerKey]; ok {
114 xapp.Logger.Debug("StartTimer() old timer found")
115 if val.timerAddress != nil {
116 xapp.Logger.Debug("StartTimer() deleting old timer")
117 val.timerAddress.Stop()
119 delete(t.timer, timerKey)
122 // Store in timerMap in-build Go "timer", timer function executor, and the function to be executed when the timer expires
123 t.timer[timerKey] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func() { t.timerFunctionExecutor(strId, nbrId) }),
124 timerFunctionAddress: func() { timerFunction(strId, nbrId) }}
128 func (t *TimerMap) StopTimer(strId string, nbrId int) bool {
130 defer t.mutex.Unlock()
131 timerKey := TimerKey{strId, nbrId}
132 if val, ok := t.timer[timerKey]; ok {
133 if val.timerAddress != nil {
134 val.timerAddress.Stop()
135 delete(t.timer, timerKey)
138 xapp.Logger.Error("StopTimer() timerAddress == nil")
142 xapp.Logger.Debug("StopTimer() Timer not found. May be expired or stopped already. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)
147 func (t *TimerMap) timerFunctionExecutor(strId string, nbrId int) {
149 timerKey := TimerKey{strId, nbrId}
150 if val, ok := t.timer[timerKey]; ok {
151 if val.timerFunctionAddress != nil {
152 // Take local copy of timer function address
153 f := val.timerFunctionAddress
154 // Delete timer instance from map
155 delete(t.timer, timerKey)
157 // Execute the timer function
161 xapp.Logger.Error("timerExecutorFunc() timerFunctionAddress == nil")
166 xapp.Logger.Error("timerExecutorFunc() Timer is not anymore in map. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)