From: Anssi Mannila Date: Tue, 17 Dec 2019 13:29:55 +0000 (+0200) Subject: RICPLT-2801 Implement Subscription Request timer, RICPLT-2801 Implement Subscription... X-Git-Tag: 0.4.0~62 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=f1d0eb6a82e11f14f60e3636d526299ced0173ea;p=ric-plt%2Fsubmgr.git RICPLT-2801 Implement Subscription Request timer, RICPLT-2801 Implement Subscription Delete Request timer, add handler call for Subscription Delete Failure and update RMR library and xapp_frame versions Change-Id: Ib1610cfa806d38bff7dc0ebad8f0b599a0919d34 Signed-off-by: Anssi Mannila --- diff --git a/Dockerfile b/Dockerfile index 6b719d1..d29864c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,9 +25,9 @@ FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:2-u18.04-nng as submgrbuild WORKDIR /tmp # Install RMr shared library -RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.9.0_amd64.deb/download.deb && dpkg -i rmr_1.9.0_amd64.deb && rm -rf rmr_1.9.0_amd64.deb +RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.0_amd64.deb/download.deb && dpkg -i rmr_1.10.0_amd64.deb && rm -rf rmr_1.10.0_amd64.deb # Install RMr development header files -RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.9.0_amd64.deb/download.deb && dpkg -i rmr-dev_1.9.0_amd64.deb && rm -rf rmr-dev_1.9.0_amd64.deb +RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.10.0_amd64.deb/download.deb && dpkg -i rmr-dev_1.10.0_amd64.deb && rm -rf rmr-dev_1.10.0_amd64.deb # "PULLING LOG and COMPILING LOG" RUN git clone "https://gerrit.o-ran-sc.org/r/com/log" /opt/log && cd /opt/log && \ diff --git a/go.mod b/go.mod index 1b1b362..eaf5baa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ go 1.12 module gerrit.o-ran-sc.org/r/ric-plt/submgr require ( - gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.20 + gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.23 github.com/go-openapi/runtime v0.19.7 github.com/go-openapi/strfmt v0.19.3 github.com/spf13/viper v1.4.0 @@ -11,6 +11,6 @@ require ( replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.2.0 -replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.20 +replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.23 replace gerrit.o-ran-sc.org/r/com/golog => gerrit.o-ran-sc.org/r/com/golog.git v0.0.1 diff --git a/pkg/control/control.go b/pkg/control/control.go index db39f7b..34dd6a0 100644 --- a/pkg/control/control.go +++ b/pkg/control/control.go @@ -34,8 +34,8 @@ import ( "sync" ) -var subReqTime time.Duration = 2 * time.Second -var SubDelReqTime time.Duration = 2 * time.Second +var subReqTime time.Duration = 5 * time.Second +var SubDelReqTime time.Duration = 5 * time.Second type Control struct { e2ap *E2ap @@ -138,6 +138,8 @@ func (c *Control) Consume(msg *xapp.RMRParams) (err error) { go c.handleSubscriptionDeleteRequest(msg) case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]: go c.handleSubscriptionDeleteResponse(msg) + case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]: + go c.handleSubscriptionDeleteFailure(msg) default: xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype) } @@ -192,9 +194,9 @@ func (c *Control) handleSubscriptionRequest(params *xapp.RMRParams) { err = c.rmrSend(params) if err != nil { xapp.Logger.Error("SubReq: Failed to send request to E2T %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) - } /*else { - c.timerMap.StartTimer(newSubId, subReqTime, c.handleSubscriptionRequestTimer) - }*/ + } else { + c.timerMap.StartTimer("RIC_SUB_REQ", int(newSubId), subReqTime, c.handleSubscriptionRequestTimer) + } xapp.Logger.Debug("SubReq: Debugging transaction table = %v", c.tracker.transactionTable) return } @@ -216,7 +218,7 @@ func (c *Control) handleSubscriptionResponse(params *xapp.RMRParams) { return } -// c.timerMap.StopTimer(payloadSeqNum) + c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum)) c.registry.setSubscriptionToConfirmed(payloadSeqNum) var transaction Transaction @@ -257,7 +259,7 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) { } xapp.Logger.Info("SubFail: Received payloadSeqNum: %v", payloadSeqNum) -// c.timerMap.StopTimer(payloadSeqNum) + c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum)) var transaction Transaction transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, CREATE) @@ -285,7 +287,7 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) { xapp.Logger.Error("SubFail: Failed to update routing manager. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) } - xapp.Logger.Info("SubFail: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) + xapp.Logger.Info("SubFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) if c.registry.releaseSequenceNumber(payloadSeqNum) { transaction, err = c.tracker.completeTransaction(payloadSeqNum, CREATE) if err != nil { @@ -299,51 +301,72 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) { return } -func (c *Control) handleSubscriptionRequestTimer(subId uint16) { - xapp.Logger.Info("Subscription Request timer expired. SubId: %v",subId) -/* +func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int) { + newSubId := uint16(nbrId) + xapp.Logger.Info("SubReq timer expired. newSubId: %v", newSubId) +// var causeContent uint8 = 1 // just some random cause. To be checked later. Should be no respose or something +// var causeVal uint8 = 1 // just some random val. To be checked later. Should be no respose or something +// c.sendSubscriptionFailure(newSubId, causeContent, causeVal) +} + +/* +func (c *Control) sendSubscriptionFailure(subId uint16, causeContent uint8, causeVal uint8) { + transaction, err := c.tracker.completeTransaction(subId, CREATE) if err != nil { - xapp.Logger.Error("Failed to delete a Subscription Request transaction record due to %v", err) + xapp.Logger.Error("SendSubFail: Failed to delete transaction record. Err:%v. SubId: %v", err, subId) return } - xapp.Logger.Info("SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid) + xapp.Logger.Info("SendSubFail: SubId: %v, Xid %v, Meid: %v", subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid) var params xapp.RMRParams params.Mtype = 12012 //xapp.RICMessageTypes["RIC_SUB_FAILURE"] params.SubId = int(subId) params.Meid = transaction.OrigParams.Meid params.Xid = transaction.OrigParams.Xid - payload := []byte("40C9408098000003EA7E00050000010016EA6300020021EA6E00808180EA6F000400000000EA6F000400010040EA6F000400020080EA6F0004000300C0EA6F000400040100EA6F000400050140EA6F000400060180EA6F0004000701C0EA6F000400080200EA6F000400090240EA6F0004000A0280EA6F0004000B02C0EA6F0004000C0300EA6F0004000D0340EA6F0004000E0380EA6F0004000F03C0") - params.PayloadLen = len(payload) - params.Payload = payload + +// newPayload, packErr := c.e2ap.PackSubscriptionFailure(transaction.OrigParams.Payload, subId, causeContent, causeVal) +// if packErr != nil { +// xapp.Logger.Error("SendSubFail: PackSubscriptionFailure() due to %v", packErr) +// return +// } + + newPayload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0") // Temporary solution + + params.PayloadLen = len(newPayload) + params.Payload = newPayload - xapp.Logger.Info("Forwarding Subscription Failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid) + xapp.Logger.Info("SendSubFail: Forwarding failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid) err = c.rmrReplyToSender(¶ms) if err != nil { - xapp.Logger.Error("Failed to send response to requestor %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid) + xapp.Logger.Error("SendSubFail: Failed to send response to xApp. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) } -*/ -/* + time.Sleep(3 * time.Second) - xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort) + xapp.Logger.Info("SendSubFail: SubId: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort) - xapp.Logger.Info("Starting routing manager update") - subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, payloadSeqNum} - c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction) + xapp.Logger.Info("SubReqTimer: Starting routing manager update. SubId: %v, Xid: %s", params.SubId, params.Xid) + subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, subId} + err = c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction) + if err != nil { + xapp.Logger.Error("SendSubFail: Failed to update routing manager %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid) + return + } - xapp.Logger.Info("Deleting trancaction record") - if c.registry.releaseSequenceNumber(payloadSeqNum) { - transaction, err = c.tracker.completeTransaction(payloadSeqNum, CREATE) + xapp.Logger.Info("SendSubFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) + if c.registry.releaseSequenceNumber(subId) { + transaction, err = c.tracker.completeTransaction(subId, CREATE) if err != nil { - xapp.Logger.Error("Failed to delete a Subscription Request transaction record due to %v", err) + xapp.Logger.Error("SendSubFail: Failed to delete transaction record. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) return } + } else { + xapp.Logger.Error("SendSubFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid) } -*/ return } +*/ func (act Action) String() string { actions := [...]string{ @@ -396,9 +419,9 @@ func (c *Control) handleSubscriptionDeleteRequest(params *xapp.RMRParams) { c.rmrSend(params) if err != nil { xapp.Logger.Error("SubDelReq: Failed to send request to E2T. Err %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) - } /*else { - c.timerMap.StartTimer(payloadSeqNum, SubDelReqTime, c.handleSubscriptionDeleteRequestTimer) - }*/ + } else { + c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum), subReqTime, c.handleSubscriptionDeleteRequestTimer) + } return } @@ -425,8 +448,8 @@ func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err } xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum) -// c.timerMap.StopTimer(payloadSeqNum) - + c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum)) + var transaction Transaction transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, DELETE) if err != nil { @@ -454,7 +477,7 @@ func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err return } - xapp.Logger.Info("SubDelResp: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) + xapp.Logger.Info("SubDelResp: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) if c.registry.releaseSequenceNumber(payloadSeqNum) { transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE) if err != nil { @@ -480,7 +503,7 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) { } xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum) -// c.timerMap.StopTimer(payloadSeqNum) + c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum)) var transaction Transaction transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, DELETE) @@ -509,7 +532,7 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) { return } - xapp.Logger.Info("SubDelFail: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) + xapp.Logger.Info("SubDelFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) if c.registry.releaseSequenceNumber(payloadSeqNum) { transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE) if err != nil { @@ -523,47 +546,68 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) { return } -func (c *Control) handleSubscriptionDeleteRequestTimer(subId uint16) { - xapp.Logger.Info("Subscription Delete Request timer expired. SubId: %v",subId) -/* +func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int) { + newSubId := uint16(nbrId) + xapp.Logger.Info("SubDelReq timer expired. newSubId: %v", newSubId) +// var causeContent uint8 = 1 // just some random cause. To be checked later. Should be no respose or something +// var causeVal uint8 = 1 // just some random val. To be checked later. Should be no respose or something +// c.sendSubscriptionDeleteFailure(newSubId, causeContent, causeVal) +} + +/* +func (c *Control) sendSubscriptionDeleteFailure(subId uint16, causeContent uint8, causeVal uint8) { transaction, err := c.tracker.completeTransaction(subId, DELETE) if err != nil { - xapp.Logger.Error("Failed to delete a Subscription Delete Request transaction record due to %v", err) + xapp.Logger.Error("SendSubDelFail: Failed to delete transaction record. Err: %v, newSubId: %v", err, subId) return } - xapp.Logger.Info("SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid) + xapp.Logger.Info("SendSubDelFail: SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid) var params xapp.RMRParams params.Mtype = 12022 //xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"] params.SubId = int(subId) params.Meid = transaction.OrigParams.Meid params.Xid = transaction.OrigParams.Xid - payload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0") - params.PayloadLen = len(payload) - params.Payload = payload + +// newPayload, packErr := c.e2ap.PackSubscriptionDeleteFailure(transaction.OrigParams.Payload, subId, causeContent, causeVal) +// if packErr != nil { +// xapp.Logger.Error("SendSubDelFail: PackSubscriptionDeleteFailure(). Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)) +// return +// } + + newPayload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0") // Temporary solution + + params.PayloadLen = len(newPayload) + params.Payload = newPayload - xapp.Logger.Info("Forwarding Subscription Delete Failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid) + xapp.Logger.Info("SendSubDelFail: Forwarding failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid) err = c.rmrReplyToSender(¶ms) if err != nil { - xapp.Logger.Error("Failed to send response to requestor %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid) + xapp.Logger.Error("SendSubDelFail: Failed to send response to xApp: Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) } -*/ -/* + time.Sleep(3 * time.Second) - xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort) + + xapp.Logger.Info("SendSubDelFail: SubId: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort) - xapp.Logger.Info("Starting routing manager update") - subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, payloadSeqNum} - c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction) + xapp.Logger.Info("SendSubDelFail: Starting routing manager update. SubId: %v, Xid: %s", params.SubId, params.Xid) + subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, subId} + err = c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction) + if err != nil { + xapp.Logger.Error("SendSubDelFail: Failed to update routing manager. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) + return + } - xapp.Logger.Info("Deleting trancaction record") - if c.registry.releaseSequenceNumber(payloadSeqNum) { - transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE) + xapp.Logger.Info("SendSubDelFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid) + if c.registry.releaseSequenceNumber(subId) { + transaction, err = c.tracker.completeTransaction(subId, DELETE) if err != nil { - xapp.Logger.Error("Failed to delete a Subscription Delete Request transaction record due to %v", err) + xapp.Logger.Error("SendSubDelFail: Failed to delete transaction record. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid) return } + } else { + xapp.Logger.Error("SendSubDelFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid) } -*/ return - } +} +*/ \ No newline at end of file diff --git a/pkg/control/timer.go b/pkg/control/timer.go new file mode 100644 index 0000000..5d48464 --- /dev/null +++ b/pkg/control/timer.go @@ -0,0 +1,170 @@ +/* +================================================================================== + Copyright (c) 2019 AT&T Intellectual Property. + Copyright (c) 2019 Nokia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================== +*/ +/* +Timer takes four parameters: + 1) strId string 'string format timerMap key' + 2) nbrId int 'numeric format timerMap key' + 3) timerDuration time.Duration 'timer duration' + 4) timerFunction func(string, int) 'function to be executed when timer expires' + + Timer function is put inside in-build time.AfterFunc() Go function, where it is run inside own Go routine + when the timer expires. Timer are two key values. Both are used always, but the other one can be left + "empty", i.e. strId = "" or nbrId = 0. Fourth parameter, the timer function is bare function name without + any function parameters and parenthesis! Filling first parameter strId with related name can improve + code readability and robustness, even the numeric Id would be enough from functionality point of view. + + TimerStart() function starts the timer. If TimerStart() function is called again with same key values + while earlier started timer is still in the timerMap, i.e. it has not been stopped or the timer has not + yet expired, the old timer is deleted and new timer is started with the given time value. + + StopTimer() function stops the timer. There is no need to call StopTimer() function after the timer has + expired. Timer is removed automatically from the timeMap. Calling StopTimer() function with key values not + existing in the timerMap, has no effect. + + NOTE: Each timer is run in separate Go routine. Therefore, the function that is executed when timer expires + MUST be designed to be able run concurrently! Also, function run order of simultaneously expired timers cannot + guaranteed anyway! + + If you need to transport more information to the timer function, consider to use another map to store the + information with same key value, as the started timer. + + Init timerMap example: + timerMap := new(TimerMap) + timerMap.Init() + + StartTimer() and StartTimer() function usage examples. + 1) + subReqTime := 2 * time.Second + subId := 123 + timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, handleSubscriptionRequestTimer) + timerMap.StopTimer("RIC_SUB_REQ", int(subId)) + + 2) + subReqTime := 2 * time.Second + strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF" + timerMap.StartTimer(strId, 0, subReqTime, handleSubscriptionRequestTimer) + timerMap.StopTimer(strId, 0) + + 3) + subReqTime := 2 * time.Second + strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF" + timerMap.StartTimer(RIC_SUB_REQ_" + strId, 0, subReqTime, handleSubscriptionRequestTimer) + timerMap.timerMap.StopTimer("RIC_SUB_REQ_" + strId, 0) + + Timer function example. This is run if any of the above started timer expires. + func handleSubscriptionRequestTimer1(strId string, nbrId int) { + fmt.Printf("Subscription Request timer expired. Name: %v, SubId: %v\n",strId, nbrId) + } +*/ + +package control + +import ( + "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" + "sync" + "time" +) + +type TimerKey struct { + strId string + nbrId int +} + +type TimerInfo struct { + timerAddress *time.Timer + timerFunctionAddress func() +} + +type TimerMap struct { + timer map[TimerKey] TimerInfo + mutex sync.Mutex +} + +// This method should run as a constructor +func (t *TimerMap) Init() { + t.timer = make(map[TimerKey] TimerInfo) +} + +func (t *TimerMap) StartTimer(strId string, nbrId int, expireAfterTime time.Duration, timerFunction func(srtId string, nbrId int)) bool { + t.mutex.Lock() + defer t.mutex.Unlock() + if (timerFunction == nil) { + xapp.Logger.Error("StartTimer() timerFunc == nil\n") + return false + } + timerKey := TimerKey{strId, nbrId} + // Stop timer if there is already timer running with the same id + if val, ok := t.timer[timerKey]; ok { + xapp.Logger.Debug("StartTimer() old timer found") + if val.timerAddress != nil { + xapp.Logger.Debug("StartTimer() deleting old timer") + val.timerAddress.Stop() + } + delete(t.timer, timerKey) + } + + // Store in timerMap in-build Go "timer", timer function executor, and the function to be executed when the timer expires + t.timer[timerKey] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func(){t.timerFunctionExecutor(strId,nbrId)}), + timerFunctionAddress: func(){timerFunction(strId,nbrId)}} + return true +} + +func (t *TimerMap) StopTimer(strId string, nbrId int) bool { + t.mutex.Lock() + defer t.mutex.Unlock() + timerKey := TimerKey{strId, nbrId} + if val, ok := t.timer[timerKey]; ok { + if val.timerAddress != nil { + val.timerAddress.Stop() + delete(t.timer, timerKey) + return true + } else { + xapp.Logger.Error("StopTimer() timerAddress == nil") + return false + } + } else { + xapp.Logger.Debug("StopTimer() Timer not found. May be expired or stopped already. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId) + return false + } +} + +func (t *TimerMap) timerFunctionExecutor(strId string, nbrId int) { + t.mutex.Lock() + timerKey := TimerKey{strId, nbrId} + if val, ok := t.timer[timerKey]; ok { + if val.timerFunctionAddress != nil { + // Take local copy of timer function address + f := val.timerFunctionAddress + // Delete timer instance from map + delete(t.timer, timerKey) + t.mutex.Unlock() + // Execute the timer function + f() + return + } else { + xapp.Logger.Error("timerExecutorFunc() timerFunctionAddress == nil") + t.mutex.Unlock() + return + } + } else { + xapp.Logger.Error("timerExecutorFunc() Timer is not anymore in map. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId) + t.mutex.Unlock() + return + } +} diff --git a/pkg/control/timers.go b/pkg/control/timers.go deleted file mode 100644 index 6f64c5b..0000000 --- a/pkg/control/timers.go +++ /dev/null @@ -1,108 +0,0 @@ -/* -================================================================================== - Copyright (c) 2019 AT&T Intellectual Property. - Copyright (c) 2019 Nokia - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -================================================================================== -*/ - -package control - -import ( - "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" - "sync" - "time" -) - -var timerMutex = &sync.Mutex{} - -type TimerInfo struct { - timerAddress *time.Timer - timerFunctionAddress func() -} - -type TimerMap struct { - timer map[uint16] TimerInfo -} - -// This method should run as a constructor -func (t *TimerMap) Init() { - t.timer = make(map[uint16] TimerInfo) -} - -func (t *TimerMap) StartTimer(subId uint16, expireAfterTime time.Duration, timerFunction func(subId uint16)) bool { - timerMutex.Lock() - defer timerMutex.Unlock() - if (timerFunction == nil) { - xapp.Logger.Error("StartTimer() timerFunc == nil") - return false - } - - // Stop timer if there is already timer running with the same id - if val, ok := t.timer[subId]; ok { - xapp.Logger.Error("StartTimer() old timer found") - if val.timerAddress != nil { - xapp.Logger.Error("StartTimer() deleting old timer") - val.timerAddress.Stop() - } - delete(t.timer, subId) - } - - // Store timer + timer function excecutor function and the function to be excecuted when timer expires, in map - t.timer[subId] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func(){t.timerFunctionExcecutor(subId)}), - timerFunctionAddress: func(){timerFunction(subId)}} - return true -} - -func (t *TimerMap) StopTimer(subId uint16) bool { - timerMutex.Lock() - defer timerMutex.Unlock() - if val, ok := t.timer[subId]; ok { - if val.timerAddress != nil { - val.timerAddress.Stop() - delete(t.timer, subId) - return true - } else { - xapp.Logger.Error("StopTimer() timerAddress == nil") - return false - } - } else { - xapp.Logger.Info("StopTimer() Timer not found. May be expired or stopped already. subId: %v",subId) - return false - } -} - -func (t *TimerMap) timerFunctionExcecutor(subId uint16) { - timerMutex.Lock() - if val, ok := t.timer[subId]; ok { - if val.timerFunctionAddress != nil { - // Take local copy of timer function address - f := val.timerFunctionAddress - // Delete timer instance from map - delete(t.timer, subId) - timerMutex.Unlock() - // Excecute the timer function - f() - return - } else { - xapp.Logger.Error("timerExcecutorFunc() timerFunctionAddress == nil") - timerMutex.Unlock() - return - } - } else { - xapp.Logger.Error("timerExcecutorFunc() Timer not anymore in map. subId: %v",subId) - timerMutex.Unlock() - return - } -}