This commit is contained in:
DanB
2014-03-31 20:29:05 +02:00
15 changed files with 122 additions and 251 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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