mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 06:09:53 +05:00
SMG SessionTTLMaxDelay for SessionTTL randomization
This commit is contained in:
@@ -272,8 +272,7 @@ const CGRATES_CFG_JSON = `
|
||||
"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, not defined by default
|
||||
//"min_session_ttl": "", // activates session_ttl randomization as minimum possible session_ttl
|
||||
//"max_session_ttl": "", // used in case of session_ttl randomization as maximum possible session_ttl, unlimited if not defined
|
||||
//"session_ttl_max_delay": "", // activates session_ttl randomization and limits the maximum possible delay
|
||||
//"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
|
||||
"session_indexes": [], // index sessions based on these fields for GetActiveSessions API
|
||||
|
||||
@@ -196,8 +196,7 @@ type SmGenericJsonCfg struct {
|
||||
Min_call_duration *string
|
||||
Max_call_duration *string
|
||||
Session_ttl *string
|
||||
Min_session_ttl *string
|
||||
Max_session_ttl *string
|
||||
Session_ttl_max_delay *string
|
||||
Session_ttl_last_used *string
|
||||
Session_ttl_usage *string
|
||||
Session_indexes *[]string
|
||||
|
||||
@@ -97,8 +97,7 @@ type SmGenericConfig struct {
|
||||
MinCallDuration time.Duration
|
||||
MaxCallDuration time.Duration
|
||||
SessionTTL time.Duration
|
||||
MinSessionTTL *time.Duration
|
||||
MaxSessionTTL *time.Duration
|
||||
SessionTTLMaxDelay *time.Duration
|
||||
SessionTTLLastUsed *time.Duration
|
||||
SessionTTLUsage *time.Duration
|
||||
SessionIndexes utils.StringMap
|
||||
@@ -156,18 +155,11 @@ func (self *SmGenericConfig) loadFromJsonCfg(jsnCfg *SmGenericJsonCfg) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Min_session_ttl != nil {
|
||||
if minSesTTL, err := utils.ParseDurationWithSecs(*jsnCfg.Min_session_ttl); err != nil {
|
||||
if jsnCfg.Session_ttl_max_delay != nil {
|
||||
if maxTTLDelay, err := utils.ParseDurationWithSecs(*jsnCfg.Session_ttl_max_delay); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.MinSessionTTL = &minSesTTL
|
||||
}
|
||||
}
|
||||
if jsnCfg.Max_session_ttl != nil {
|
||||
if maxSesTTL, err := utils.ParseDurationWithSecs(*jsnCfg.Max_session_ttl); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.MaxSessionTTL = &maxSesTTL
|
||||
self.SessionTTLMaxDelay = &maxTTLDelay
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_ttl_last_used != nil {
|
||||
|
||||
@@ -20,6 +20,7 @@ package sessionmanager
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -185,17 +186,47 @@ func (self SMGenericEvent) GetLastUsed(fieldName string) (time.Duration, error)
|
||||
}
|
||||
|
||||
// GetSessionTTL retrieves SessionTTL setting out of SMGenericEvent
|
||||
func (self SMGenericEvent) GetSessionTTL() time.Duration {
|
||||
func (self SMGenericEvent) GetSessionTTL(sesTTL time.Duration, cfgSessionTTLMaxDelay *time.Duration) time.Duration {
|
||||
valIf, hasVal := self[utils.SessionTTL]
|
||||
if !hasVal {
|
||||
return time.Duration(0)
|
||||
if hasVal {
|
||||
ttlStr, converted := utils.ConvertIfaceToString(valIf)
|
||||
if !converted {
|
||||
utils.Logger.Warning(fmt.Sprintf("SMGenericEvent, cannot convert SessionTTL, disabling functionality for event: <%s>",
|
||||
self.GetCGRID(utils.META_DEFAULT)))
|
||||
return time.Duration(0)
|
||||
}
|
||||
var err error
|
||||
if sesTTL, err = utils.ParseDurationWithSecs(ttlStr); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("SMGenericEvent, cannot parse SessionTTL, disabling functionality for event: <%s>",
|
||||
self.GetCGRID(utils.META_DEFAULT)))
|
||||
return time.Duration(0)
|
||||
}
|
||||
}
|
||||
ttlStr, converted := utils.ConvertIfaceToString(valIf)
|
||||
if !converted {
|
||||
return time.Duration(0)
|
||||
// Variable sessionTTL
|
||||
var sessionTTLMaxDelay int64
|
||||
if cfgSessionTTLMaxDelay != nil {
|
||||
sessionTTLMaxDelay = cfgSessionTTLMaxDelay.Nanoseconds() / 1000000 // Milliseconds precision
|
||||
}
|
||||
ttl, _ := utils.ParseDurationWithSecs(ttlStr)
|
||||
return ttl
|
||||
if sesTTLMaxDelayIf, hasVal := self[utils.SessionTTLMaxDelay]; hasVal {
|
||||
maxTTLDelaxStr, converted := utils.ConvertIfaceToString(sesTTLMaxDelayIf)
|
||||
if !converted {
|
||||
utils.Logger.Warning(fmt.Sprintf("SMGenericEvent, cannot convert SessionTTLMaxDelay, disabling functionality for event: <%s>",
|
||||
self.GetCGRID(utils.META_DEFAULT)))
|
||||
return time.Duration(0)
|
||||
}
|
||||
if maxTTLDelay, err := utils.ParseDurationWithSecs(maxTTLDelaxStr); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("SMGenericEvent, cannot parse SessionTTLMaxDelay, disabling functionality for event: <%s>",
|
||||
self.GetCGRID(utils.META_DEFAULT)))
|
||||
return time.Duration(0)
|
||||
} else {
|
||||
sessionTTLMaxDelay = maxTTLDelay.Nanoseconds() / 1000000
|
||||
}
|
||||
}
|
||||
if sessionTTLMaxDelay != 0 {
|
||||
rand.Seed(time.Now().Unix())
|
||||
sesTTL += time.Duration(rand.Int63n(sessionTTLMaxDelay) * 1000000)
|
||||
}
|
||||
return sesTTL
|
||||
}
|
||||
|
||||
// GetSessionTTLLastUsed retrieves SessionTTLLastUsed setting out of SMGenericEvent
|
||||
|
||||
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package sessionmanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -132,6 +133,26 @@ func TestSMGenericEventParseFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSMGenericEventGetSessionTTL(t *testing.T) {
|
||||
smGev := SMGenericEvent{}
|
||||
smGev[utils.EVENT_NAME] = "TEST_SESSION_TTL"
|
||||
cfgSesTTL := time.Duration(5 * time.Second)
|
||||
if sTTL := smGev.GetSessionTTL(time.Duration(5*time.Second), nil); sTTL != cfgSesTTL {
|
||||
t.Errorf("Expecting: %v, received: %v", cfgSesTTL, sTTL)
|
||||
}
|
||||
smGev[utils.SessionTTL] = "6s"
|
||||
eSesTTL := time.Duration(6 * time.Second)
|
||||
if sTTL := smGev.GetSessionTTL(time.Duration(5*time.Second), nil); sTTL != eSesTTL {
|
||||
t.Errorf("Expecting: %v, received: %v", eSesTTL, sTTL)
|
||||
}
|
||||
sesTTLMaxDelay := time.Duration(10 * time.Second)
|
||||
if sTTL := smGev.GetSessionTTL(time.Duration(5*time.Second), &sesTTLMaxDelay); sTTL == eSesTTL || sTTL > eSesTTL+sesTTLMaxDelay {
|
||||
t.Errorf("Received: %v", sTTL)
|
||||
} else {
|
||||
fmt.Println(sTTL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSMGenericEventAsStoredCdr(t *testing.T) {
|
||||
smGev := SMGenericEvent{}
|
||||
smGev[utils.EVENT_NAME] = "TEST_EVENT"
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
|
||||
const (
|
||||
MaxTimespansInCost = 50
|
||||
MaxSessionTTL = 10000 // maximum session TTL in miliseconds
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -118,10 +119,8 @@ type smgSessionTerminator struct {
|
||||
|
||||
// setSessionTerminator installs a new terminator for a session
|
||||
func (smg *SMGeneric) setSessionTerminator(s *SMGSession) {
|
||||
ttl := smg.cgrCfg.SmGenericConfig.SessionTTL
|
||||
if ttlEv := s.EventStart.GetSessionTTL(); ttlEv != 0 {
|
||||
ttl = ttlEv
|
||||
}
|
||||
ttl := s.EventStart.GetSessionTTL(smg.cgrCfg.SmGenericConfig.SessionTTL,
|
||||
smg.cgrCfg.SmGenericConfig.SessionTTLMaxDelay)
|
||||
if ttl == 0 {
|
||||
return
|
||||
}
|
||||
@@ -730,7 +729,9 @@ func (smg *SMGeneric) UpdateSession(gev SMGenericEvent, clnt rpcclient.RpcClient
|
||||
}
|
||||
smg.replicateSessionsWithID(initialCGRID, false, smg.smgReplConns)
|
||||
}
|
||||
smg.resetTerminatorTimer(cgrID, gev.GetSessionTTL(), gev.GetSessionTTLLastUsed(), gev.GetSessionTTLUsage())
|
||||
smg.resetTerminatorTimer(cgrID,
|
||||
gev.GetSessionTTL(smg.cgrCfg.SmGenericConfig.SessionTTL, smg.cgrCfg.SmGenericConfig.SessionTTLMaxDelay),
|
||||
gev.GetSessionTTLLastUsed(), gev.GetSessionTTLUsage())
|
||||
var lastUsed *time.Duration
|
||||
var evLastUsed time.Duration
|
||||
if evLastUsed, err = gev.GetLastUsed(utils.META_DEFAULT); err == nil {
|
||||
|
||||
@@ -309,6 +309,7 @@ const (
|
||||
InstanceID = "InstanceID"
|
||||
ActiveGoroutines = "ActiveGoroutines"
|
||||
SessionTTL = "SessionTTL"
|
||||
SessionTTLMaxDelay = "SessionTTLMaxDelay"
|
||||
SessionTTLLastUsed = "SessionTTLLastUsed"
|
||||
SessionTTLUsage = "SessionTTLUsage"
|
||||
HandlerSubstractUsage = "*substract_usage"
|
||||
|
||||
Reference in New Issue
Block a user