call duration fixes and switch relative start/end time

This commit is contained in:
Radu Ioan Fericean
2013-08-06 22:11:03 +03:00
parent f07a0cc885
commit 0785874357
4 changed files with 35 additions and 22 deletions

View File

@@ -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

View File

@@ -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())
}

View File

@@ -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
}

View File

@@ -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)
}