From 8276ea73b79bf75342d0bbff2786c94f5ff8d216 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Mon, 31 Mar 2014 14:06:46 +0300 Subject: [PATCH 1/3] removed amount related stuff from calldesc --- engine/account.go | 19 +++------ engine/account_test.go | 87 ++--------------------------------------- engine/calldesc.go | 86 ++++++++-------------------------------- engine/calldesc_test.go | 12 +++--- engine/responder.go | 63 ++--------------------------- engine/storage_test.go | 2 +- 6 files changed, 35 insertions(+), 234 deletions(-) diff --git a/engine/account.go b/engine/account.go index cce870291..8a433ef30 100644 --- a/engine/account.go +++ b/engine/account.go @@ -34,11 +34,11 @@ const ( INBOUND = "*in" OUTBOUND = "*out" // Balance types - CREDIT = "*monetary" - SMS = "*sms" - TRAFFIC = "*internet" - TRAFFIC_TIME = "*internet_time" - MINUTES = "*minutes" + CREDIT = "*monetary" + SMS = "*sms" + DATA = "*data" + DATA_TIME = "*data_time" + MINUTES = "*minutes" // action price type PRICE_PERCENT = "*percent" PRICE_ABSOLUTE = "*absolute" @@ -310,15 +310,6 @@ func (ub *Account) refundIncrement(increment *Increment, direction string, count } } -// Debits some amount of user's specified balance. Returns the remaining credit in user's balance. -func (ub *Account) debitGenericBalance(balanceId string, direction string, amount float64, count bool) float64 { - if count { - ub.countUnits(&Action{BalanceType: balanceId, Direction: direction, Balance: &Balance{Value: amount}}) - } - ub.BalanceMap[balanceId+direction].Debit(amount) - return ub.BalanceMap[balanceId+direction].GetTotalValue() -} - // Scans the action trigers and execute the actions for which trigger is met func (ub *Account) executeActionTriggers(a *Action) { ub.ActionTriggers.Sort() diff --git a/engine/account_test.go b/engine/account_test.go index ca82447d3..f09cff846 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -157,47 +157,6 @@ func TestAccountStorageStore(t *testing.T) { } } -func TestDebitMoneyBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} - result := rifsBalance.debitGenericBalance(CREDIT, OUTBOUND, 6, false) - if rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 15 || result != rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 15, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) - } -} - -func TestDebitAllMoneyBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} - rifsBalance.debitGenericBalance(CREDIT, OUTBOUND, 21, false) - result := rifsBalance.debitGenericBalance(CREDIT, OUTBOUND, 0, false) - if rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 0 || result != rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 0, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) - } -} - -func TestDebitMoreMoneyBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} - result := rifsBalance.debitGenericBalance(CREDIT, OUTBOUND, 22, false) - if rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != -1 || result != rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", -1, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) - } -} - -func TestDebitNegativeMoneyBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} - result := rifsBalance.debitGenericBalance(CREDIT, OUTBOUND, -15, false) - if rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 36 || result != rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 36, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) - } -} - func TestDebitCreditZeroSecond(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1s"} cc := &CallCost{ @@ -791,51 +750,11 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) { } } -func TestDebitSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitGenericBalance(SMS, OUTBOUND, 12, false) - if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 88 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 88, rifsBalance.BalanceMap[SMS+OUTBOUND]) - } -} - -func TestDebitAllSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitGenericBalance(SMS, OUTBOUND, 100, false) - if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 0 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 0, rifsBalance.BalanceMap[SMS+OUTBOUND]) - } -} - -func TestDebitMoreSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitGenericBalance(SMS, OUTBOUND, 110, false) - if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != -10 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", -10, rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value) - } -} - -func TestDebitNegativeSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} - rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitGenericBalance(SMS, OUTBOUND, -15, false) - if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 115 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { - t.Errorf("Expected %v was %v", 115, rifsBalance.BalanceMap[SMS+OUTBOUND]) - } -} - func TestAccountdebitBalance(t *testing.T) { ub := &Account{ Id: "rif", AllowNegative: true, - BalanceMap: map[string]BalanceChain{SMS: BalanceChain{&Balance{Value: 14}}, TRAFFIC: BalanceChain{&Balance{Value: 1204}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, + BalanceMap: map[string]BalanceChain{SMS: BalanceChain{&Balance{Value: 14}}, DATA: BalanceChain{&Balance{Value: 1204}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, } newMb := &Balance{Weight: 20, DestinationId: "NEW"} a := &Action{BalanceType: MINUTES, Direction: OUTBOUND, Balance: newMb} @@ -850,7 +769,7 @@ func TestAccountdebitBalanceExists(t *testing.T) { ub := &Account{ Id: "rif", AllowNegative: true, - BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 15, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, + BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, DATA + OUTBOUND: BalanceChain{&Balance{Value: 1024}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 15, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, } newMb := &Balance{Value: -10, Weight: 20, DestinationId: "NAT"} a := &Action{BalanceType: MINUTES, Direction: OUTBOUND, Balance: newMb} @@ -864,7 +783,7 @@ func TestAccountAddMinuteNil(t *testing.T) { ub := &Account{ Id: "rif", AllowNegative: true, - BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, + BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, DATA + OUTBOUND: BalanceChain{&Balance{Value: 1024}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, } ub.debitBalanceAction(nil) if len(ub.BalanceMap[MINUTES+OUTBOUND]) != 2 { diff --git a/engine/calldesc.go b/engine/calldesc.go index c1497a303..ce4031bc8 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -112,11 +112,11 @@ type CallDescriptor struct { TimeStart, TimeEnd time.Time LoopIndex float64 // indicates the position of this segment in a cost request loop CallDuration time.Duration // the call duration so far (till TimeEnd) - Amount float64 - FallbackSubject string // the subject to check for destination if not found on primary subject - RatingInfos RatingInfos - Increments Increments - account *Account + //Amount float64 + FallbackSubject string // the subject to check for destination if not found on primary subject + RatingInfos RatingInfos + Increments Increments + account *Account } func (cd *CallDescriptor) ValidateCallData() error { @@ -609,60 +609,6 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) { return 0.0, err } -/* -Interface method used to add/substract an amount of cents from user's money balance. -The amount filed has to be filled in call descriptor. -*/ -func (cd *CallDescriptor) DebitCents() (left float64, err error) { - if userBalance, err := cd.getAccount(); err == nil && userBalance != nil { - defer accountingStorage.SetAccount(userBalance) - return userBalance.debitGenericBalance(CREDIT, cd.Direction, cd.Amount, true), nil - } - return 0.0, err -} - -/* -Interface method used to add/substract an amount of units from user's sms balance. -The amount filed has to be filled in call descriptor. -*/ -func (cd *CallDescriptor) DebitSMS() (left float64, err error) { - if userBalance, err := cd.getAccount(); err == nil && userBalance != nil { - defer accountingStorage.SetAccount(userBalance) - return userBalance.debitGenericBalance(SMS, cd.Direction, cd.Amount, true), nil - } - return 0, err -} - -/* -Interface method used to add/substract an amount of seconds from user's minutes balance. -The amount filed has to be filled in call descriptor. -*/ -func (cd *CallDescriptor) DebitSeconds() (err error) { - if userBalance, err := cd.getAccount(); err == nil && userBalance != nil { - defer accountingStorage.SetAccount(userBalance) - return userBalance.debitCreditBalance(cd.CreateCallCost(), true) - } - return err -} - -/* -Adds the specified amount of seconds to the received call seconds. When the threshold specified -in the user's tariff plan is reached then the received call balance is reseted and the bonus -specified in the tariff plan is applied. -The amount filed has to be filled in call descriptor. -*/ -func (cd *CallDescriptor) AddRecievedCallSeconds() (err error) { - if userBalance, err := cd.getAccount(); err == nil && userBalance != nil { - a := &Action{ - Direction: INBOUND, - Balance: &Balance{Value: cd.Amount, DestinationId: cd.Destination}, - } - userBalance.countUnits(a) - return nil - } - return err -} - func (cd *CallDescriptor) FlushCache() (err error) { cache2go.XFlush() cache2go.Flush() @@ -686,17 +632,17 @@ func (cd *CallDescriptor) CreateCallCost() *CallCost { func (cd *CallDescriptor) Clone() *CallDescriptor { return &CallDescriptor{ - Direction: cd.Direction, - TOR: cd.TOR, - Tenant: cd.Tenant, - Subject: cd.Subject, - Account: cd.Account, - Destination: cd.Destination, - TimeStart: cd.TimeStart, - TimeEnd: cd.TimeEnd, - LoopIndex: cd.LoopIndex, - CallDuration: cd.CallDuration, - Amount: cd.Amount, + Direction: cd.Direction, + TOR: cd.TOR, + Tenant: cd.Tenant, + Subject: cd.Subject, + Account: cd.Account, + Destination: cd.Destination, + TimeStart: cd.TimeStart, + TimeEnd: cd.TimeEnd, + LoopIndex: cd.LoopIndex, + CallDuration: cd.CallDuration, + // Amount: cd.Amount, FallbackSubject: cd.FallbackSubject, //RatingInfos: cd.RatingInfos, //Increments: cd.Increments, diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index af96ca572..df4b3a303 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -425,7 +425,7 @@ func TestMaxSessionTimeWithAccountAccount(t *testing.T) { Subject: "minu_from_tm", Account: "minu", Destination: "0723", - Amount: 1000} + } result, err := cd.GetMaxSessionDuration() expected := time.Minute if result != expected || err != nil { @@ -442,7 +442,7 @@ func TestMaxSessionTimeNoCredit(t *testing.T) { Tenant: "vdf", Subject: "broker", Destination: "0723", - Amount: 5400} + } result, err := cd.GetMaxSessionDuration() if result != time.Minute || err != nil { t.Errorf("Expected %v was %v", time.Minute, result) @@ -462,7 +462,7 @@ func TestMaxSessionModifiesCallDesc(t *testing.T) { Account: "minu", Destination: "0723", CallDuration: t2.Sub(t1), - Amount: 5400} + } initial := cd.Clone() cd.GetMaxSessionDuration() cd.account = nil // it's OK to cache the account @@ -481,7 +481,7 @@ func TestMaxDebitDurationNoGreatherThanInitialDuration(t *testing.T) { Subject: "minu_from_tm", Account: "minu", Destination: "0723", - Amount: 1000} + } initialDuration := cd.TimeEnd.Sub(cd.TimeStart) result, _ := cd.GetMaxSessionDuration() if result > initialDuration { @@ -671,7 +671,7 @@ func BenchmarkSplitting(b *testing.B) { func BenchmarkStorageSingleGetSessionTime(b *testing.B) { b.StopTimer() - cd := &CallDescriptor{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Amount: 100} + cd := &CallDescriptor{Tenant: "vdf", Subject: "minutosu", Destination: "0723"} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetMaxSessionDuration() @@ -680,7 +680,7 @@ func BenchmarkStorageSingleGetSessionTime(b *testing.B) { func BenchmarkStorageMultipleGetSessionTime(b *testing.B) { b.StopTimer() - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minutosu", Destination: "0723", Amount: 5400} + cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minutosu", Destination: "0723"} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetMaxSessionDuration() diff --git a/engine/responder.go b/engine/responder.go index f135b8378..84096ab6a 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -89,42 +89,6 @@ func (rs *Responder) RefundIncrements(arg CallDescriptor, reply *float64) (err e return } -func (rs *Responder) DebitCents(arg CallDescriptor, reply *float64) (err error) { - if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.DebitCents") - } else { - r, e := AccLock.Guard(arg.GetAccountKey(), func() (float64, error) { - return arg.DebitCents() - }) - *reply, err = r, e - } - return -} - -func (rs *Responder) DebitSMS(arg CallDescriptor, reply *float64) (err error) { - if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.DebitSMS") - } else { - r, e := AccLock.Guard(arg.GetAccountKey(), func() (float64, error) { - return arg.DebitSMS() - }) - *reply, err = r, e - } - return -} - -func (rs *Responder) DebitSeconds(arg CallDescriptor, reply *float64) (err error) { - if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.DebitSeconds") - } else { - r, e := AccLock.Guard(arg.GetAccountKey(), func() (float64, error) { - return 0, arg.DebitSeconds() - }) - *reply, err = r, e - } - return -} - func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err error) { if rs.Bal != nil { *reply, err = rs.callMethod(&arg, "Responder.GetMaxSessionTime") @@ -138,19 +102,6 @@ func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err return } -func (rs *Responder) AddRecievedCallSeconds(arg CallDescriptor, reply *float64) (err error) { - if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.AddRecievedCallSeconds") - } else { - - r, e := AccLock.Guard(arg.GetAccountKey(), func() (float64, error) { - return 0, arg.AddRecievedCallSeconds() - }) - *reply, err = r, e - } - return -} - func (rs *Responder) FlushCache(arg CallDescriptor, reply *float64) (err error) { if rs.Bal != nil { *reply, err = rs.callMethod(&arg, "Responder.FlushCache") @@ -200,12 +151,12 @@ func (rs *Responder) GetSMS(arg CallDescriptor, reply *CallCost) (err error) { } func (rs *Responder) GetInternet(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, TRAFFIC, reply) + err = rs.getBalance(&arg, DATA, reply) return err } func (rs *Responder) GetInternetTime(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, TRAFFIC_TIME, reply) + err = rs.getBalance(&arg, DATA_TIME, reply) return err } @@ -355,8 +306,6 @@ type Connector interface { Debit(CallDescriptor, *CallCost) error MaxDebit(CallDescriptor, *CallCost) error RefundIncrements(CallDescriptor, *float64) error - DebitCents(CallDescriptor, *float64) error - DebitSeconds(CallDescriptor, *float64) error GetMaxSessionTime(CallDescriptor, *float64) error } @@ -375,15 +324,11 @@ func (rcc *RPCClientConnector) Debit(cd CallDescriptor, cc *CallCost) error { func (rcc *RPCClientConnector) MaxDebit(cd CallDescriptor, cc *CallCost) error { return rcc.Client.Call("Responder.MaxDebit", cd, cc) } + func (rcc *RPCClientConnector) RefundIncrements(cd CallDescriptor, resp *float64) error { return rcc.Client.Call("Responder.RefundIncrements", cd, resp) } -func (rcc *RPCClientConnector) DebitCents(cd CallDescriptor, resp *float64) error { - return rcc.Client.Call("Responder.DebitCents", cd, resp) -} -func (rcc *RPCClientConnector) DebitSeconds(cd CallDescriptor, resp *float64) error { - return rcc.Client.Call("Responder.DebitSeconds", cd, resp) -} + func (rcc *RPCClientConnector) GetMaxSessionTime(cd CallDescriptor, resp *float64) error { return rcc.Client.Call("Responder.GetMaxSessionTime", cd, resp) } diff --git a/engine/storage_test.go b/engine/storage_test.go index e67d9e437..b34cdb618 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -147,7 +147,7 @@ func GetUB() *Account { ub := &Account{ Id: "rif", AllowNegative: true, - BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14, ExpirationDate: zeroTime}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024, ExpirationDate: zeroTime}}, MINUTES: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, + BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14, ExpirationDate: zeroTime}}, DATA + OUTBOUND: BalanceChain{&Balance{Value: 1024, ExpirationDate: zeroTime}}, MINUTES: BalanceChain{&Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{uc, uc}, ActionTriggers: ActionTriggerPriotityList{at, at, at}, } From a8e4dad5f0adea33fd7f6fb1cd1e8c0759974820 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Mon, 31 Mar 2014 14:18:02 +0300 Subject: [PATCH 2/3] removed rateing id from callcost and loader --- engine/loader_csv_test.go | 3 --- engine/loader_helpers.go | 1 - engine/rateinterval.go | 1 - 3 files changed, 5 deletions(-) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index df45fddce..46e51ecf4 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -495,7 +495,6 @@ func TestLoadDestinationRateTimings(t *testing.T) { }, Ratings: map[string]*RIRate{ "d54545c1": &RIRate{ - Id: "R1", ConnectFee: 0, Rates: []*Rate{ &Rate{ @@ -509,7 +508,6 @@ func TestLoadDestinationRateTimings(t *testing.T) { RoundingDecimals: 2, }, "4bb00b9c": &RIRate{ - Id: "R2", ConnectFee: 0, Rates: []*Rate{ &Rate{ @@ -523,7 +521,6 @@ func TestLoadDestinationRateTimings(t *testing.T) { RoundingDecimals: 2, }, "e06c337f": &RIRate{ - Id: "R3", ConnectFee: 0, Rates: []*Rate{ &Rate{ diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index 0b712e29d..16c5f52e1 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -126,7 +126,6 @@ func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate) }, Weight: rpl.Weight, Rating: &RIRate{ - Id: dr.Rate.RateId, ConnectFee: dr.Rate.RateSlots[0].ConnectFee, RoundingMethod: dr.Rate.RateSlots[0].RoundingMethod, RoundingDecimals: dr.Rate.RateSlots[0].RoundingDecimals, diff --git a/engine/rateinterval.go b/engine/rateinterval.go index 190c310c7..a7522c1a6 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -53,7 +53,6 @@ func (rit *RITiming) Stringify() string { // Separate structure used for rating plan size optimization type RIRate struct { - Id string // informational role only ConnectFee float64 Rates RateGroups // GroupRateInterval (start time): Rate RoundingMethod string //ROUNDING_UP, ROUNDING_DOWN, ROUNDING_MIDDLE From 62c56ae26b0c5cc90f831a8c672e7e8452524ec4 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Mon, 31 Mar 2014 21:01:52 +0300 Subject: [PATCH 3/3] stale destination prefix cleaning --- cache2go/cache.go | 41 ++++++++++++++++++++++++++++--------- engine/destinations.go | 27 +++++++++++++++++++++++- engine/destinations_test.go | 16 +++++++++++++++ engine/storage_map.go | 2 ++ engine/storage_redis.go | 1 + utils/slice.go | 12 ++++++++++- 6 files changed, 87 insertions(+), 12 deletions(-) diff --git a/cache2go/cache.go b/cache2go/cache.go index b7ab7c47e..5f63c6be7 100644 --- a/cache2go/cache.go +++ b/cache2go/cache.go @@ -135,16 +135,6 @@ func RemKey(key string) { delete(cache, key) } -func RemPrefixKey(prefix string) { - mux.Lock() - defer mux.Unlock() - for key, _ := range cache { - if strings.HasPrefix(key, prefix) { - delete(cache, key) - } - } -} - func XRemKey(key string) { xMux.Lock() defer xMux.Unlock() @@ -155,6 +145,17 @@ func XRemKey(key string) { } delete(xcache, key) } + +func RemPrefixKey(prefix string) { + mux.Lock() + defer mux.Unlock() + for key, _ := range cache { + if strings.HasPrefix(key, prefix) { + delete(cache, key) + } + } +} + func XRemPrefixKey(prefix string) { xMux.Lock() defer xMux.Unlock() @@ -170,6 +171,26 @@ func XRemPrefixKey(prefix string) { } } +func GetAllEntries(prefix string) map[string]interface{} { + result := make(map[string]interface{}) + for key, timestampedValue := range cache { + if strings.HasPrefix(key, prefix) { + result[key] = timestampedValue.value + } + } + return result +} + +func XGetAllEntries(prefix string) map[string]interface{} { + result := make(map[string]interface{}) + for key, value := range xcache { + if strings.HasPrefix(key, prefix) { + result[key] = value + } + } + return result +} + // Delete all keys from expiraton cache func XFlush() { xMux.Lock() diff --git a/engine/destinations.go b/engine/destinations.go index 8d4e1df4c..caa42abbd 100644 --- a/engine/destinations.go +++ b/engine/destinations.go @@ -20,9 +20,11 @@ package engine import ( "encoding/json" - "github.com/cgrates/cgrates/cache2go" "strings" + "github.com/cgrates/cgrates/cache2go" + "github.com/cgrates/cgrates/utils" + "github.com/cgrates/cgrates/history" ) @@ -81,3 +83,26 @@ func CachedDestHasPrefix(destId, prefix string) bool { } return false } + +func CleanStalePrefixes(destIds []string) { + prefixMap := cache2go.GetAllEntries(DESTINATION_PREFIX) + for prefix, idIDs := range prefixMap { + dIDs := idIDs.([]string) + changed := false + for _, searchedDID := range destIds { + if found, i := utils.GetSliceMemberIndex(dIDs, searchedDID); found { + if len(dIDs) == 1 { + // remove de prefix from cache + cache2go.RemKey(prefix) + } else { + // delte the testination from list and put the new list in chache + dIDs[i], dIDs = dIDs[len(dIDs)-1], dIDs[:len(dIDs)-1] + changed = true + } + } + } + if changed { + cache2go.Cache(prefix, dIDs) + } + } +} diff --git a/engine/destinations_test.go b/engine/destinations_test.go index 95cd1bd5e..2ae708c9e 100644 --- a/engine/destinations_test.go +++ b/engine/destinations_test.go @@ -125,6 +125,22 @@ func TestNonCachedDestWrongPrefix(t *testing.T) { } } +func TestCleanStalePrefixes(t *testing.T) { + cache2go.Cache(DESTINATION_PREFIX+"1", []string{"D1", "D2"}) + cache2go.Cache(DESTINATION_PREFIX+"2", []string{"D1"}) + cache2go.Cache(DESTINATION_PREFIX+"3", []string{"D2"}) + CleanStalePrefixes([]string{"D1"}) + if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.([]string)) != 1 { + t.Error("Error cleaning stale destination ids", r) + } + if r, err := cache2go.GetCached(DESTINATION_PREFIX + "2"); err == nil { + t.Error("Error removing stale prefix: ", r) + } + if r, err := cache2go.GetCached(DESTINATION_PREFIX + "3"); err != nil || len(r.([]string)) != 1 { + t.Error("Error performing stale cleaning: ", r) + } +} + /********************************* Benchmarks **********************************/ func BenchmarkDestinationStorageStoreRestore(b *testing.B) { diff --git a/engine/storage_map.go b/engine/storage_map.go index 844859f13..949101744 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -51,6 +51,8 @@ func (ms *MapStorage) Flush() error { func (ms *MapStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys []string) error { if dKeys == nil { cache2go.RemPrefixKey(DESTINATION_PREFIX) + } else { + CleanStalePrefixes(dKeys) } if rpKeys == nil { cache2go.RemPrefixKey(RATING_PLAN_PREFIX) diff --git a/engine/storage_redis.go b/engine/storage_redis.go index a8ac83288..82dd1ddc5 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -76,6 +76,7 @@ func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys []string) (e cache2go.RemPrefixKey(DESTINATION_PREFIX) } else if len(dKeys) != 0 { Logger.Info(fmt.Sprintf("Caching destinations: %v", dKeys)) + CleanStalePrefixes(dKeys) } for _, key := range dKeys { if _, err = rs.GetDestination(key[len(DESTINATION_PREFIX):]); err != nil { diff --git a/utils/slice.go b/utils/slice.go index d31026767..5465adb98 100644 --- a/utils/slice.go +++ b/utils/slice.go @@ -32,7 +32,17 @@ func IsSliceMember(ss []string, s string) bool { return false } -//Iterates over slice members and returns true of one starts with prefix +// Binary string search in slice +// returns true if found and the index +func GetSliceMemberIndex(ss []string, s string) (bool, int) { + sort.Strings(ss) + if i := sort.SearchStrings(ss, s); i < len(ss) && ss[i] == s { + return true, i + } + return false, len(ss) +} + +//Iterates over slice members and returns true if one starts with prefix func SliceMemberHasPrefix(ss []string, prfx string) bool { for _, mbr := range ss { if strings.HasPrefix(mbr, prfx) {