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) tryCount uint64 'tryCount'
25 5) timerFunction func(string, int) 'function to be executed when timer expires'
27 Timer function is put inside in-build time.AfterFunc() Go function, where it is run inside own Go routine
28 when the timer expires. Timer are two key values. Both are used always, but the other one can be left
29 "empty", i.e. strId = "" or nbrId = 0. Fourth parameter is for tryCount. Fifth parameter, the timer
30 function is bare function name without any function parameters and parenthesis! Filling first parameter
31 strId with related name can improve code readability and robustness, even the numeric Id would be enough
32 from functionality point of view.
34 TimerStart() function starts the timer. If TimerStart() function is called again with same key values
35 while earlier started timer is still in the timerMap, i.e. it has not been stopped or the timer has not
36 yet expired, the old timer is deleted and new timer is started with the given time value.
38 StopTimer() function stops the timer. There is no need to call StopTimer() function after the timer has
39 expired. Timer is removed automatically from the timeMap. Calling StopTimer() function with key values not
40 existing in the timerMap, has no effect.
42 NOTE: Each timer is run in separate Go routine. Therefore, the function that is executed when timer expires
43 MUST be designed to be able run concurrently! Also, function run order of simultaneously expired timers cannot
46 If you need to transport more information to the timer function, consider to use another map to store the
47 information with same key value, as the started timer.
49 Init timerMap example:
50 timerMap := new(TimerMap)
53 StartTimer() and StartTimer() function usage examples.
55 subReqTime := 2 * time.Second
57 var tryCount uint64 = 1
58 timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, FirstTry, handleSubscriptionRequestTimer)
59 timerMap.StopTimer("RIC_SUB_REQ", int(subId))
62 StartTimer() retry example.
64 subReqTime := 2 * time.Second
66 var tryCount uint64 = 1
67 timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, FirstTry, handleSubscriptionRequestTimer)
68 timerMap.StopTimer("RIC_SUB_REQ", int(subId))
71 subReqTime := 2 * time.Second
72 strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
73 var tryCount uint64 = 1
74 timerMap.StartTimer(strId, 0, subReqTime, FirstTry, handleSubscriptionRequestTimer)
75 timerMap.StopTimer(strId, 0)
78 subReqTime := 2 * time.Second
79 strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
80 var tryCount uint64 = 1
81 timerMap.StartTimer(RIC_SUB_REQ_" + strId, 0, subReqTime, FirstTry, handleSubscriptionRequestTimer)
82 timerMap.timerMap.StopTimer("RIC_SUB_REQ_" + strId, 0)
84 Timer function example. This is run if any of the above started timer expires.
85 func handleSubscriptionRequestTimer1(strId string, nbrId int, tryCount uint64) {
86 fmt.Printf("Subscription Request timer expired. Name: %v, SubId: %v, tryCount: %v\n",strId, nbrId, tryCount)
93 timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, tryCount, handleSubscriptionRequestTimer)
102 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
109 type TimerKey struct {
114 type TimerInfo struct {
115 timerAddress *time.Timer
116 timerFunctionAddress func()
119 type TimerMap struct {
120 timer map[TimerKey]TimerInfo
124 // This method should run as a constructor
125 func (t *TimerMap) Init() {
126 t.timer = make(map[TimerKey]TimerInfo)
129 func (t *TimerMap) StartTimer(strId string, nbrId int, expireAfterTime time.Duration, tryCount uint64, timerFunction func(srtId string, nbrId int, tryCount uint64)) bool {
131 defer t.mutex.Unlock()
132 if timerFunction == nil {
133 xapp.Logger.Error("StartTimer() timerFunc == nil\n")
136 timerKey := TimerKey{strId, nbrId}
137 // Stop timer if there is already timer running with the same id
138 if val, ok := t.timer[timerKey]; ok {
139 xapp.Logger.Debug("StartTimer() old timer found")
140 if val.timerAddress != nil {
141 xapp.Logger.Debug("StartTimer() deleting old timer")
142 val.timerAddress.Stop()
144 delete(t.timer, timerKey)
147 // Store in timerMap in-build Go "timer", timer function executor and the function to be executed when the timer expires
148 t.timer[timerKey] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func() { t.timerFunctionExecutor(strId, nbrId) }),
149 timerFunctionAddress: func() { timerFunction(strId, nbrId, tryCount) }}
153 func (t *TimerMap) StopTimer(strId string, nbrId int) bool {
155 defer t.mutex.Unlock()
156 timerKey := TimerKey{strId, nbrId}
157 if val, ok := t.timer[timerKey]; ok {
158 if val.timerAddress != nil {
159 val.timerAddress.Stop()
160 delete(t.timer, timerKey)
163 xapp.Logger.Error("StopTimer() timerAddress == nil")
167 xapp.Logger.Debug("StopTimer() Timer not found. May be expired or stopped already. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)
172 func (t *TimerMap) timerFunctionExecutor(strId string, nbrId int) {
174 timerKey := TimerKey{strId, nbrId}
175 if val, ok := t.timer[timerKey]; ok {
176 if val.timerFunctionAddress != nil {
177 // Take local copy of timer function address
178 f := val.timerFunctionAddress
179 // Delete timer instance from map
180 delete(t.timer, timerKey)
182 // Execute the timer function
186 xapp.Logger.Error("timerExecutorFunc() timerFunctionAddress == nil")
191 xapp.Logger.Error("timerExecutorFunc() Timer is not anymore in map. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)