mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 14:19:54 +05:00
SMG - SessionTTLUsage and SessionTTLLastUsed support
This commit is contained in:
@@ -210,7 +210,9 @@ const CGRATES_CFG_JSON = `
|
||||
"debit_interval": "0s", // interval to perform debits on.
|
||||
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
|
||||
"max_call_duration": "3h", // maximum call duration a prepaid call can last
|
||||
"session_ttl": "0s", // time after a session with no updates is terminated
|
||||
"session_ttl": "0s", // time after a session with no updates is terminated, not defined by default
|
||||
//"session_ttl_last_used": "", // tweak LastUsed for sessions timing-out, not defined by default
|
||||
//"session_ttl_usage": "", // tweak Usage for sessions timing-out, not defined by default
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -167,14 +167,16 @@ type CdrcJsonCfg struct {
|
||||
|
||||
// SM-Generic config section
|
||||
type SmGenericJsonCfg struct {
|
||||
Enabled *bool
|
||||
Listen_bijson *string
|
||||
Rater *string
|
||||
Cdrs *string
|
||||
Debit_interval *string
|
||||
Min_call_duration *string
|
||||
Max_call_duration *string
|
||||
Session_ttl *string
|
||||
Enabled *bool
|
||||
Listen_bijson *string
|
||||
Rater *string
|
||||
Cdrs *string
|
||||
Debit_interval *string
|
||||
Min_call_duration *string
|
||||
Max_call_duration *string
|
||||
Session_ttl *string
|
||||
Session_ttl_last_used *string
|
||||
Session_ttl_usage *string
|
||||
}
|
||||
|
||||
// SM-FreeSWITCH config section
|
||||
|
||||
@@ -72,14 +72,16 @@ func (self *FsConnConfig) loadFromJsonCfg(jsnCfg *FsConnJsonCfg) error {
|
||||
}
|
||||
|
||||
type SmGenericConfig struct {
|
||||
Enabled bool
|
||||
ListenBijson string
|
||||
HaRater []*HaPoolConfig
|
||||
HaCdrs []*HaPoolConfig
|
||||
DebitInterval time.Duration
|
||||
MinCallDuration time.Duration
|
||||
MaxCallDuration time.Duration
|
||||
SessionTTL time.Duration
|
||||
Enabled bool
|
||||
ListenBijson string
|
||||
HaRater []*HaPoolConfig
|
||||
HaCdrs []*HaPoolConfig
|
||||
DebitInterval time.Duration
|
||||
MinCallDuration time.Duration
|
||||
MaxCallDuration time.Duration
|
||||
SessionTTL time.Duration
|
||||
SessionTTLLastUsed *time.Duration
|
||||
SessionTTLUsage *time.Duration
|
||||
}
|
||||
|
||||
func (self *SmGenericConfig) loadFromJsonCfg(jsnCfg *SmGenericJsonCfg) error {
|
||||
@@ -119,6 +121,20 @@ func (self *SmGenericConfig) loadFromJsonCfg(jsnCfg *SmGenericJsonCfg) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_ttl_last_used != nil {
|
||||
if sessionTTLLastUsed, err := utils.ParseDurationWithSecs(*jsnCfg.Session_ttl_last_used); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.SessionTTLLastUsed = &sessionTTLLastUsed
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_ttl_usage != nil {
|
||||
if sessionTTLUsage, err := utils.ParseDurationWithSecs(*jsnCfg.Session_ttl_usage); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.SessionTTLUsage = &sessionTTLUsage
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -51,34 +51,75 @@ type SMGeneric struct {
|
||||
guard *engine.GuardianLock // Used to lock on uuid
|
||||
}
|
||||
type smgSessionTerminator struct {
|
||||
timer *time.Timer
|
||||
endChan chan bool
|
||||
timer *time.Timer
|
||||
endChan chan bool
|
||||
ttl time.Duration
|
||||
ttlLastUsed *time.Duration
|
||||
ttlUsage *time.Duration
|
||||
}
|
||||
|
||||
// Updates the timer for the session to a new ttl and terminate info
|
||||
func (self *SMGeneric) resetTerminatorTimer(uuid string, ttl time.Duration, ttlLastUsed, ttlUsage *time.Duration) {
|
||||
self.sessionsMux.RLock()
|
||||
defer self.sessionsMux.RUnlock()
|
||||
if st, found := self.sessionTerminators[uuid]; found {
|
||||
if ttl != 0 {
|
||||
st.ttl = ttl
|
||||
}
|
||||
if ttlLastUsed != nil {
|
||||
st.ttlLastUsed = ttlLastUsed
|
||||
}
|
||||
if ttlUsage != nil {
|
||||
st.ttlUsage = ttlUsage
|
||||
}
|
||||
st.timer.Reset(st.ttl)
|
||||
}
|
||||
}
|
||||
|
||||
// Called when a session timeouts
|
||||
func (self *SMGeneric) ttlTerminate(s *SMGSession, tmtr *smgSessionTerminator) {
|
||||
totalSessionUsage := s.TotalUsage() + tmtr.ttl
|
||||
if tmtr.ttlUsage != nil {
|
||||
totalSessionUsage = *tmtr.ttlUsage
|
||||
}
|
||||
if totalSessionUsage > s.TotalUsage() {
|
||||
evUpdate := s.eventStart
|
||||
diffSessionUsage := totalSessionUsage - s.TotalUsage()
|
||||
evUpdate[utils.USAGE] = diffSessionUsage.Seconds() // Debit additionally
|
||||
if tmtr.ttlLastUsed != nil {
|
||||
evUpdate[utils.LastUsed] = tmtr.ttlLastUsed.Seconds()
|
||||
}
|
||||
self.SessionUpdate(evUpdate, nil)
|
||||
}
|
||||
self.sessionEnd(s.eventStart.GetUUID(), totalSessionUsage)
|
||||
cdr := s.eventStart.AsStoredCdr(self.cgrCfg, self.timezone)
|
||||
cdr.Usage = totalSessionUsage
|
||||
var reply string
|
||||
self.cdrsrv.ProcessCdr(cdr, &reply)
|
||||
}
|
||||
|
||||
func (self *SMGeneric) indexSession(uuid string, s *SMGSession) {
|
||||
self.sessionsMux.Lock()
|
||||
self.sessions[uuid] = append(self.sessions[uuid], s)
|
||||
if self.cgrCfg.SmGenericConfig.SessionTTL > 0 {
|
||||
if self.cgrCfg.SmGenericConfig.SessionTTL != 0 {
|
||||
if _, found := self.sessionTerminators[uuid]; !found {
|
||||
timer := time.NewTimer(self.cgrCfg.SmGenericConfig.SessionTTL)
|
||||
endChan := make(chan bool, 1)
|
||||
terminator := &smgSessionTerminator{
|
||||
timer: timer,
|
||||
endChan: endChan,
|
||||
ttl: self.cgrCfg.SmGenericConfig.SessionTTL,
|
||||
}
|
||||
self.sessionTerminators[uuid] = terminator
|
||||
go func() {
|
||||
select {
|
||||
case <-timer.C:
|
||||
totalUsage := s.TotalUsage() + self.cgrCfg.SmGenericConfig.SessionTTL
|
||||
self.sessionEnd(uuid, totalUsage)
|
||||
cdr := s.eventStart.AsStoredCdr(self.cgrCfg, self.timezone)
|
||||
cdr.Usage = totalUsage
|
||||
var reply string
|
||||
self.cdrsrv.ProcessCdr(cdr, &reply)
|
||||
self.ttlTerminate(s, terminator)
|
||||
case <-endChan:
|
||||
timer.Stop()
|
||||
}
|
||||
}()
|
||||
self.sessionTerminators[uuid] = &smgSessionTerminator{
|
||||
timer: timer,
|
||||
endChan: endChan,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
self.sessionsMux.Unlock()
|
||||
@@ -125,15 +166,6 @@ func (self *SMGeneric) getSession(uuid string) []*SMGSession {
|
||||
return self.sessions[uuid]
|
||||
}
|
||||
|
||||
// Updates the timer for the session to a new ttl
|
||||
func (self *SMGeneric) resetTerminatorTimer(uuid string) {
|
||||
self.sessionsMux.RLock()
|
||||
defer self.sessionsMux.RUnlock()
|
||||
if st, found := self.sessionTerminators[uuid]; found {
|
||||
st.timer.Reset(self.cgrCfg.SmGenericConfig.SessionTTL)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle a new session, pass the connectionId so we can communicate on disconnect request
|
||||
func (self *SMGeneric) sessionStart(evStart SMGenericEvent, connId string) error {
|
||||
sessionId := evStart.GetUUID()
|
||||
@@ -262,7 +294,21 @@ func (self *SMGeneric) SessionStart(gev SMGenericEvent, clnt *rpc2.Client) (time
|
||||
|
||||
// Execute debits for usage/maxUsage
|
||||
func (self *SMGeneric) SessionUpdate(gev SMGenericEvent, clnt *rpc2.Client) (time.Duration, error) {
|
||||
self.resetTerminatorTimer(gev.GetUUID())
|
||||
ttl := time.Duration(0)
|
||||
if ttlStr, err := gev.GetFieldAsString(utils.SessionTTL); err == nil {
|
||||
ttl, _ = utils.ParseDurationWithSecs(ttlStr)
|
||||
}
|
||||
var ttlLastUsed *time.Duration
|
||||
if ttlLastUsedStr, err := gev.GetFieldAsString(utils.SessionTTLLastUsed); err == nil {
|
||||
ttlLastUsedParsed, _ := utils.ParseDurationWithSecs(ttlLastUsedStr)
|
||||
ttlLastUsed = &ttlLastUsedParsed
|
||||
}
|
||||
var ttlUsage *time.Duration
|
||||
if ttlUsageStr, err := gev.GetFieldAsString(utils.SessionTTLUsage); err == nil {
|
||||
ttlUsageParsed, _ := utils.ParseDurationWithSecs(ttlUsageStr)
|
||||
ttlUsage = &ttlUsageParsed
|
||||
}
|
||||
self.resetTerminatorTimer(gev.GetUUID(), ttl, ttlLastUsed, ttlUsage)
|
||||
if initialID, err := gev.GetFieldAsString(utils.InitialOriginID); err == nil {
|
||||
err := self.sessionRelocate(gev.GetUUID(), initialID)
|
||||
if err == utils.ErrNotFound { // Session was already relocated, create a new session with this update
|
||||
|
||||
@@ -278,6 +278,9 @@ const (
|
||||
UpdatedAt = "UpdatedAt"
|
||||
HandlerArgSep = "|"
|
||||
FlagForceDuration = "fd"
|
||||
SessionTTL = "SessionTTL"
|
||||
SessionTTLLastUsed = "SessionTTLLastUsed"
|
||||
SessionTTLUsage = "SessionTTLUsage"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user