mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 14:19:54 +05:00
call duration fixes and switch relative start/end time
This commit is contained in:
@@ -97,8 +97,8 @@ type CallDescriptor struct {
|
||||
TOR string
|
||||
Tenant, Subject, Account, Destination string
|
||||
TimeStart, TimeEnd time.Time
|
||||
LoopIndex float64 // indicates the postion of this segment in a cost request loop
|
||||
CallDuration float64 // the call duration so far (partial or final)
|
||||
LoopIndex float64 // indicates the postion of this segment in a cost request loop
|
||||
CallDuration time.Duration // the call duration so far (partial or final)
|
||||
Amount float64
|
||||
FallbackSubject string // the subject to check for destination if not found on primary subject
|
||||
ActivationPeriods []*ActivationPeriod
|
||||
@@ -188,7 +188,7 @@ Splits the received timespan into sub time spans according to the activation per
|
||||
*/
|
||||
func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*TimeSpan) {
|
||||
if firstSpan == nil {
|
||||
firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd}
|
||||
firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration.Seconds()}
|
||||
}
|
||||
timespans = append(timespans, firstSpan)
|
||||
// split on (free) minute buckets
|
||||
@@ -317,7 +317,7 @@ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) {
|
||||
Logger.Debug(fmt.Sprintf("available sec: %v credit: %v", availableSeconds, availableCredit))
|
||||
}
|
||||
} else {
|
||||
Logger.Err(fmt.Sprintf("Could not get user balance for %s.", cd.GetUserBalanceKey()))
|
||||
Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetUserBalanceKey(), err.Error()))
|
||||
return cd.Amount, err
|
||||
}
|
||||
// check for zero balance
|
||||
|
||||
@@ -118,7 +118,7 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) {
|
||||
ts.TimeEnd = splitTime
|
||||
nts.SetInterval(i)
|
||||
nts.CallDuration = ts.CallDuration
|
||||
ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds())
|
||||
ts.SetNewCallDuration(nts)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -141,7 +141,7 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) {
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd}
|
||||
ts.TimeEnd = splitTime
|
||||
nts.CallDuration = ts.CallDuration
|
||||
ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds())
|
||||
ts.SetNewCallDuration(nts)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -157,7 +157,7 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) {
|
||||
|
||||
nts.SetInterval(i)
|
||||
nts.CallDuration = ts.CallDuration
|
||||
ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds())
|
||||
ts.SetNewCallDuration(nts)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -172,7 +172,9 @@ func (ts *TimeSpan) SplitByActivationPeriod(ap *ActivationPeriod) (newTs *TimeSp
|
||||
return nil
|
||||
}
|
||||
newTs = &TimeSpan{TimeStart: ap.ActivationTime, TimeEnd: ts.TimeEnd, ActivationPeriod: ap}
|
||||
newTs.CallDuration = ts.CallDuration
|
||||
ts.TimeEnd = ap.ActivationTime
|
||||
ts.SetNewCallDuration(newTs)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -189,7 +191,9 @@ func (ts *TimeSpan) SplitByMinuteBucket(mb *MinuteBucket) (newTs *TimeSpan) {
|
||||
|
||||
if !mb.ExpirationDate.IsZero() && ts.TimeEnd.After(mb.ExpirationDate) {
|
||||
newTs = &TimeSpan{TimeStart: mb.ExpirationDate, TimeEnd: ts.TimeEnd}
|
||||
newTs.CallDuration = ts.CallDuration
|
||||
ts.TimeEnd = mb.ExpirationDate
|
||||
ts.SetNewCallDuration(newTs)
|
||||
}
|
||||
|
||||
s := ts.GetDuration().Seconds()
|
||||
@@ -203,7 +207,9 @@ func (ts *TimeSpan) SplitByMinuteBucket(mb *MinuteBucket) (newTs *TimeSpan) {
|
||||
newTimeEnd := ts.TimeStart.Add(secDuration)
|
||||
newTs = &TimeSpan{TimeStart: newTimeEnd, TimeEnd: ts.TimeEnd}
|
||||
ts.TimeEnd = newTimeEnd
|
||||
newTs.CallDuration = ts.CallDuration
|
||||
ts.MinuteInfo.Quantity = mb.Seconds
|
||||
ts.SetNewCallDuration(newTs)
|
||||
mb.Seconds = 0
|
||||
|
||||
return
|
||||
@@ -216,3 +222,7 @@ func (ts *TimeSpan) GetGroupStart() float64 {
|
||||
func (ts *TimeSpan) GetGroupEnd() float64 {
|
||||
return ts.CallDuration
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) SetNewCallDuration(nts *TimeSpan) {
|
||||
ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds())
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) {
|
||||
if s == nil { // Not handled by us
|
||||
return
|
||||
}
|
||||
defer s.Close() // Stop loop and save the costs deducted so far to database
|
||||
defer s.Close(ev) // Stop loop and save the costs deducted so far to database
|
||||
if ev.GetReqType() == utils.POSTPAID {
|
||||
startTime, err := ev.GetStartTime(START_TIME)
|
||||
if err != nil {
|
||||
@@ -213,7 +213,7 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) {
|
||||
Subject: ev.GetSubject(),
|
||||
Account: ev.GetAccount(),
|
||||
LoopIndex: 0,
|
||||
CallDuration: endTime.Sub(startTime).Seconds(),
|
||||
CallDuration: endTime.Sub(startTime),
|
||||
Destination: ev.GetDestination(),
|
||||
TimeStart: startTime,
|
||||
TimeEnd: endTime,
|
||||
@@ -310,7 +310,7 @@ func (sm *FSSessionManager) LoopAction(s *Session, cd *engine.CallDescriptor, in
|
||||
cc := &engine.CallCost{}
|
||||
cd.LoopIndex = index
|
||||
cd.Amount = sm.debitPeriod.Seconds()
|
||||
cd.CallDuration += cd.Amount
|
||||
cd.CallDuration += time.Duration(cd.Amount) * time.Second
|
||||
err := sm.connector.MaxDebit(*cd, cc)
|
||||
if err != nil {
|
||||
engine.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err))
|
||||
@@ -330,9 +330,11 @@ func (sm *FSSessionManager) LoopAction(s *Session, cd *engine.CallDescriptor, in
|
||||
}
|
||||
s.CallCosts = append(s.CallCosts, cc)
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) GetDebitPeriod() time.Duration {
|
||||
return sm.debitPeriod
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) GetDbLogger() engine.DataStorage {
|
||||
return sm.loggerDB
|
||||
}
|
||||
|
||||
@@ -81,18 +81,18 @@ func NewSession(ev Event, sm SessionManager) (s *Session) {
|
||||
func (s *Session) startDebitLoop() {
|
||||
nextCd := *s.callDescriptor
|
||||
index := 0.0
|
||||
ticker := time.NewTicker(s.sessionManager.GetDebitPeriod())
|
||||
for {
|
||||
select {
|
||||
case <-s.stopDebit:
|
||||
return
|
||||
default:
|
||||
case <-ticker.C:
|
||||
}
|
||||
if nextCd.TimeEnd != s.callDescriptor.TimeEnd { // first time use the session start time
|
||||
nextCd.TimeStart = time.Now()
|
||||
if index > 0 { // first time use the session start time
|
||||
nextCd.TimeStart = nextCd.TimeEnd
|
||||
}
|
||||
nextCd.TimeEnd = time.Now().Add(s.sessionManager.GetDebitPeriod())
|
||||
nextCd.TimeEnd = nextCd.TimeStart.Add(s.sessionManager.GetDebitPeriod())
|
||||
s.sessionManager.LoopAction(s, &nextCd, index)
|
||||
time.Sleep(s.sessionManager.GetDebitPeriod())
|
||||
index++
|
||||
}
|
||||
}
|
||||
@@ -107,19 +107,20 @@ func (s *Session) getSessionDurationFrom(now time.Time) (d time.Duration) {
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the session duration till now
|
||||
func (s *Session) GetSessionDuration() time.Duration {
|
||||
return s.getSessionDurationFrom(time.Now())
|
||||
}
|
||||
|
||||
// Stops the debit loop
|
||||
func (s *Session) Close() {
|
||||
func (s *Session) Close(ev Event) {
|
||||
engine.Logger.Debug(fmt.Sprintf("Stopping debit for %s", s.uuid))
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
s.stopDebit <- true
|
||||
s.callDescriptor.TimeEnd = time.Now()
|
||||
//s.callDescriptor.TimeEnd = time.Now()
|
||||
endTime, err := ev.GetEndTime()
|
||||
if err != nil {
|
||||
engine.Logger.Err("Error parsing answer event stop time.")
|
||||
endTime = s.callDescriptor.TimeStart.Add(s.callDescriptor.CallDuration)
|
||||
}
|
||||
s.callDescriptor.TimeEnd = endTime
|
||||
s.SaveOperations()
|
||||
s.sessionManager.RemoveSession(s)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user