working version for cache transactions

This commit is contained in:
Radu Ioan Fericean
2014-09-03 19:17:10 +03:00
parent 90f77cf158
commit 24c79b6b22
14 changed files with 184 additions and 156 deletions

View File

@@ -11,6 +11,7 @@ import (
const (
PREFIX_LEN = 4
KIND_ADD = "ADD"
KIND_ADP = "ADP"
KIND_REM = "REM"
KIND_PRF = "PRF"
)
@@ -63,6 +64,8 @@ func CommitTransaction() {
RemPrefixKey(item.key)
case KIND_ADD:
Cache(item.key, item.value)
case KIND_ADP:
CachePush(item.key, item.value)
}
}
mux.Unlock()
@@ -83,11 +86,40 @@ func Cache(key string, value interface{}) {
count(key)
}
cache[key] = timestampedValue{time.Now(), value}
//fmt.Println("ADD: ", key)
} else {
transactionBuffer = append(transactionBuffer, transactionItem{key: key, value: value, kind: KIND_ADD})
}
}
// Appends to an existing slice in the cache key
func CachePush(key string, val interface{}) {
if !transactionLock {
mux.Lock()
defer mux.Unlock()
}
if !transactionON {
var elements []interface{}
if ti, exists := cache[key]; exists {
elements = ti.value.([]interface{})
}
// check if the val is already present
found := false
for _, v := range elements {
if val == v {
found = true
break
}
}
if !found {
elements = append(elements, val)
}
cache[key] = timestampedValue{time.Now(), elements}
} else {
transactionBuffer = append(transactionBuffer, transactionItem{key: key, value: val, kind: KIND_ADP})
}
}
// The function to extract a value for a key that never expire
func GetCached(key string) (v interface{}, err error) {
mux.RLock()
@@ -114,6 +146,7 @@ func RemKey(key string) {
}
if !transactionON {
if _, ok := cache[key]; ok {
//fmt.Println("REM: ", key)
delete(cache, key)
descount(key)
}
@@ -127,15 +160,16 @@ func RemPrefixKey(prefix string) {
mux.Lock()
defer mux.Unlock()
}
for key, _ := range cache {
if !transactionON {
if !transactionON {
for key, _ := range cache {
if strings.HasPrefix(key, prefix) {
//fmt.Println("PRF: ", key)
delete(cache, key)
descount(key)
}
}
}
if transactionON {
} else {
transactionBuffer = append(transactionBuffer, transactionItem{key: prefix, kind: KIND_PRF})
}
}

View File

@@ -85,6 +85,15 @@ func TestRemPrefixKey(t *testing.T) {
}
}
func TestCachePush(t *testing.T) {
CachePush("x_t1", "1")
CachePush("x_t1", "2")
v, err := GetCached("x_t1")
if err != nil || len(v.([]interface{})) != 2 {
t.Error("Error in cache push: ", v)
}
}
func TestCount(t *testing.T) {
Cache("dst_A1", "1")
Cache("dst_A2", "2")

View File

@@ -160,7 +160,7 @@ func (ub *Account) getBalancesForPrefix(prefix, category string, balances Balanc
if b.DestinationId != "" && b.DestinationId != utils.ANY {
for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]string)
destIds := x.([]interface{})
for _, dId := range destIds {
if dId == b.DestinationId {
b.precision = len(p)

View File

@@ -35,7 +35,7 @@ const (
RECURSION_MAX_DEPTH = 3
MIN_PREFIX_MATCH = 1
FALLBACK_SUBJECT = utils.ANY
DEBUG = false
DEBUG = true
)
func init() {

View File

@@ -75,7 +75,7 @@ func (d *Destination) GetHistoryRecord() history.Record {
// Reverse search in cache to see if prefix belongs to destination id
func CachedDestHasPrefix(destId, prefix string) bool {
if cached, err := cache2go.GetCached(DESTINATION_PREFIX + prefix); err == nil {
for _, cachedDstId := range cached.([]string) {
for _, cachedDstId := range cached.([]interface{}) {
if destId == cachedDstId {
return true
}
@@ -87,10 +87,10 @@ func CachedDestHasPrefix(destId, prefix string) bool {
func CleanStalePrefixes(destIds []string) {
prefixMap := cache2go.GetAllEntries(DESTINATION_PREFIX)
for prefix, idIDs := range prefixMap {
dIDs := idIDs.([]string)
dIDs := idIDs.([]interface{})
changed := false
for _, searchedDID := range destIds {
if found, i := utils.GetSliceMemberIndex(dIDs, searchedDID); found {
if i, found := utils.GetSliceMemberIndex(utils.ConvertInterfaceSliceToStringSlice(dIDs), searchedDID); found {
if len(dIDs) == 1 {
// remove de prefix from cache
cache2go.RemKey(prefix)

View File

@@ -126,17 +126,17 @@ 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"})
cache2go.Cache(DESTINATION_PREFIX+"1", []interface{}{"D1", "D2"})
cache2go.Cache(DESTINATION_PREFIX+"2", []interface{}{"D1"})
cache2go.Cache(DESTINATION_PREFIX+"3", []interface{}{"D2"})
CleanStalePrefixes([]string{"D1"})
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.([]string)) != 1 {
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.([]interface{})) != 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 {
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "3"); err != nil || len(r.([]interface{})) != 1 {
t.Error("Error performing stale cleaning: ", r)
}
}

View File

@@ -31,11 +31,7 @@ var acntDb AccountingStorage
func init() {
cfgDcT, _ = config.NewDefaultCGRConfig()
if DEBUG {
acntDb, _ = NewMapStorage()
} else {
acntDb, _ = NewRedisStorage("127.0.0.1:6379", 13, "", utils.MSGPACK)
}
acntDb = accountingStorage
acntDb.CacheAccounting(nil, nil, nil, nil)
}

View File

@@ -127,8 +127,9 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
} else {
for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]string)
for _, dId := range destIds {
destIds := x.([]interface{})
for _, idId := range destIds {
dId := idId.(string)
if _, ok := rpl.DestinationRates[dId]; ok {
rps = rpl.RateIntervalList(dId)
prefix = p

View File

@@ -40,6 +40,6 @@ func TestResponderGetDerivedChargers(t *testing.T) {
t.Error("Unexpected error", err.Error())
} else if !reflect.DeepEqual(dcs, cfgedDC) {
//t.Errorf("Expecting: %v, received: %v ", cfgedDC, dcs)
//TODO: fix the above test when DEBUG=false
//FIXME: fix the above test
}
}

View File

@@ -53,6 +53,7 @@ func (ms *MapStorage) Flush() error {
}
func (ms *MapStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) error {
cache2go.BeginTransaction()
if dKeys == nil {
cache2go.RemPrefixKey(DESTINATION_PREFIX)
} else {
@@ -70,7 +71,6 @@ func (ms *MapStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []str
if lcrKeys == nil {
cache2go.RemPrefixKey(LCR_PREFIX)
}
cache2go.BeginTransaction()
for k, _ := range ms.dict {
if strings.HasPrefix(k, DESTINATION_PREFIX) {
if _, err := ms.GetDestination(k[len(DESTINATION_PREFIX):]); err != nil {
@@ -172,13 +172,12 @@ func (ms *MapStorage) HasData(categ, subject string) (bool, error) {
return false, errors.New("Unsupported category")
}
func (ms *MapStorage) GetRatingPlan(key string, checkDb bool) (rp *RatingPlan, err error) {
func (ms *MapStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) {
key = RATING_PLAN_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingPlan), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingPlan), nil
}
}
if values, ok := ms.dict[key]; ok {
b := bytes.NewBuffer(values)
@@ -215,13 +214,12 @@ func (ms *MapStorage) SetRatingPlan(rp *RatingPlan) (err error) {
return
}
func (ms *MapStorage) GetRatingProfile(key string, checkDb bool) (rpf *RatingProfile, err error) {
func (ms *MapStorage) GetRatingProfile(key string, skipCache bool) (rpf *RatingProfile, err error) {
key = RATING_PROFILE_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingProfile), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingProfile), nil
}
}
if values, ok := ms.dict[key]; ok {
rpf = new(RatingProfile)
@@ -245,13 +243,12 @@ func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
return
}
func (ms *MapStorage) GetLCR(key string, checkDb bool) (lcr *LCR, err error) {
func (ms *MapStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) {
key = LCR_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*LCR), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*LCR), nil
}
}
if values, ok := ms.dict[key]; ok {
err = ms.ms.Unmarshal(values, &lcr)
@@ -269,13 +266,12 @@ func (ms *MapStorage) SetLCR(lcr *LCR) (err error) {
return
}
func (ms *MapStorage) GetRpAlias(key string, checkDb bool) (alias string, err error) {
func (ms *MapStorage) GetRpAlias(key string, skipCache bool) (alias string, err error) {
key = RP_ALIAS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
if !checkDb {
return "", errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
}
if values, ok := ms.dict[key]; ok {
alias = string(values)
@@ -311,18 +307,21 @@ func (ms *MapStorage) RemoveRpAliases(tenantRtSubjects []*TenantRatingSubject) (
return
}
func (ms *MapStorage) GetRPAliases(tenant, subject string, checkDb bool) (aliases []string, err error) {
func (ms *MapStorage) GetRPAliases(tenant, subject string, skipCache bool) (aliases []string, err error) {
tenantPrfx := RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
alsKeys := cache2go.GetEntriesKeys(tenantPrfx)
var alsKeys []string
if !skipCache {
alsKeys = cache2go.GetEntriesKeys(tenantPrfx)
}
for _, key := range alsKeys {
if alsSubj, err := ms.GetRpAlias(key[len(RP_ALIAS_PREFIX):], checkDb); err != nil {
if alsSubj, err := ms.GetRpAlias(key[len(RP_ALIAS_PREFIX):], skipCache); err != nil {
return nil, err
} else if alsSubj == subject {
alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant
aliases = append(aliases, alsFromKey)
}
}
if len(alsKeys) == 0 && checkDb {
if len(alsKeys) == 0 {
for key, value := range ms.dict {
if strings.HasPrefix(key, RP_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && subject == string(value) {
aliases = append(aliases, key[len(tenantPrfx):])
@@ -332,13 +331,12 @@ func (ms *MapStorage) GetRPAliases(tenant, subject string, checkDb bool) (aliase
return aliases, nil
}
func (ms *MapStorage) GetAccAlias(key string, checkDb bool) (alias string, err error) {
func (ms *MapStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) {
key = ACC_ALIAS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
if !checkDb {
return "", errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
}
if values, ok := ms.dict[key]; ok {
alias = string(values)
@@ -367,7 +365,7 @@ func (ms *MapStorage) RemoveAccAliases(tenantAccounts []*TenantAccount) (err err
return
}
func (ms *MapStorage) GetAccountAliases(tenant, account string, checkDb bool) (aliases []string, err error) {
func (ms *MapStorage) GetAccountAliases(tenant, account string, skipCache bool) (aliases []string, err error) {
for key, value := range ms.dict {
tenantPrfx := ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
if strings.HasPrefix(key, ACC_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && account == string(value) {
@@ -394,14 +392,7 @@ func (ms *MapStorage) GetDestination(key string) (dest *Destination, err error)
err = ms.ms.Unmarshal(out, dest)
// create optimized structure
for _, p := range dest.Prefixes {
var ids []string
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
ids = x.([]string)
}
if !utils.IsSliceMember(ids, dest.Id) {
ids = append(ids, dest.Id)
}
cache2go.Cache(DESTINATION_PREFIX+p, ids)
cache2go.CachePush(DESTINATION_PREFIX+p, dest.Id)
}
} else {
return nil, errors.New("not found")
@@ -424,13 +415,12 @@ func (ms *MapStorage) SetDestination(dest *Destination) (err error) {
return
}
func (ms *MapStorage) GetActions(key string, checkDb bool) (as Actions, err error) {
func (ms *MapStorage) GetActions(key string, skipCache bool) (as Actions, err error) {
key = ACTION_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(Actions), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(Actions), nil
}
}
if values, ok := ms.dict[key]; ok {
err = ms.ms.Unmarshal(values, &as)
@@ -448,13 +438,12 @@ func (ms *MapStorage) SetActions(key string, as Actions) (err error) {
return
}
func (ms *MapStorage) GetSharedGroup(key string, checkDb bool) (sg *SharedGroup, err error) {
func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) {
key = SHARED_GROUP_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*SharedGroup), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*SharedGroup), nil
}
}
if values, ok := ms.dict[key]; ok {
err = ms.ms.Unmarshal(values, &sg)
@@ -529,13 +518,12 @@ func (ms *MapStorage) GetAllActionTimings() (ats map[string]ActionPlan, err erro
return
}
func (ms *MapStorage) GetDerivedChargers(key string, checkDb bool) (dcs utils.DerivedChargers, err error) {
func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) {
key = DERIVEDCHARGERS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(utils.DerivedChargers), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(utils.DerivedChargers), nil
}
}
if values, ok := ms.dict[key]; ok {
err = ms.ms.Unmarshal(values, &dcs)

View File

@@ -67,7 +67,7 @@ func (rs *RedisStorage) Flush() (err error) {
return
}
func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) error {
func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []string) (err error) {
cache2go.BeginTransaction()
if dKeys == nil {
Logger.Info("Caching all destinations")
@@ -173,7 +173,7 @@ func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []s
return nil
}
func (rs *RedisStorage) CacheAccounting(actKeys, shgKeys, alsKeys, dcsKeys []string) error {
func (rs *RedisStorage) CacheAccounting(actKeys, shgKeys, alsKeys, dcsKeys []string) (err error) {
cache2go.BeginTransaction()
if actKeys == nil {
cache2go.RemPrefixKey(ACTION_PREFIX)
@@ -273,13 +273,12 @@ func (rs *RedisStorage) HasData(category, subject string) (bool, error) {
return false, errors.New("Unsupported category in ExistsData")
}
func (rs *RedisStorage) GetRatingPlan(key string, checkDb bool) (rp *RatingPlan, err error) {
func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) {
key = RATING_PLAN_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingPlan), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingPlan), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -315,13 +314,13 @@ func (rs *RedisStorage) SetRatingPlan(rp *RatingPlan) (err error) {
return
}
func (rs *RedisStorage) GetRatingProfile(key string, checkDb bool) (rpf *RatingProfile, err error) {
func (rs *RedisStorage) GetRatingProfile(key string, skipCache bool) (rpf *RatingProfile, err error) {
key = RATING_PROFILE_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingProfile), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*RatingProfile), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -343,14 +342,12 @@ func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
return
}
func (rs *RedisStorage) GetRpAlias(key string, checkDb bool) (alias string, err error) {
func (rs *RedisStorage) GetRpAlias(key string, skipCache bool) (alias string, err error) {
key = RP_ALIAS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
if !checkDb {
return "", errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -394,16 +391,19 @@ func (rs *RedisStorage) RemoveRpAliases(tenantRtSubjects []*TenantRatingSubject)
return
}
func (rs *RedisStorage) GetRPAliases(tenant, subject string, checkDb bool) (aliases []string, err error) {
func (rs *RedisStorage) GetRPAliases(tenant, subject string, skipCache bool) (aliases []string, err error) {
tenantPrfx := RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
alsKeys := cache2go.GetEntriesKeys(tenantPrfx)
if len(alsKeys) == 0 && checkDb {
var alsKeys []string
if !skipCache {
alsKeys = cache2go.GetEntriesKeys(tenantPrfx)
}
if len(alsKeys) == 0 {
if alsKeys, err = rs.db.Keys(tenantPrfx + "*"); err != nil {
return nil, err
}
}
for _, key := range alsKeys {
if alsSubj, err := rs.GetRpAlias(key[len(RP_ALIAS_PREFIX):], checkDb); err != nil {
if alsSubj, err := rs.GetRpAlias(key[len(RP_ALIAS_PREFIX):], skipCache); err != nil {
return nil, err
} else if alsSubj == subject {
alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant
@@ -413,13 +413,12 @@ func (rs *RedisStorage) GetRPAliases(tenant, subject string, checkDb bool) (alia
return aliases, nil
}
func (rs *RedisStorage) GetLCR(key string, checkDb bool) (lcr *LCR, err error) {
func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) {
key = LCR_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*LCR), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*LCR), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -436,13 +435,12 @@ func (rs *RedisStorage) SetLCR(lcr *LCR) (err error) {
return
}
func (rs *RedisStorage) GetAccAlias(key string, checkDb bool) (alias string, err error) {
func (rs *RedisStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) {
key = ACC_ALIAS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
if !checkDb {
return "", errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(string), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -486,17 +484,20 @@ func (rs *RedisStorage) RemoveAccAliases(tenantAccounts []*TenantAccount) (err e
}
// Returns the aliases of one specific account on a tenant
func (rs *RedisStorage) GetAccountAliases(tenant, account string, checkDb bool) (aliases []string, err error) {
func (rs *RedisStorage) GetAccountAliases(tenant, account string, skipCache bool) (aliases []string, err error) {
tenantPrfx := ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
alsKeys := cache2go.GetEntriesKeys(tenantPrfx)
if len(alsKeys) == 0 && checkDb {
var alsKeys []string
if !skipCache {
alsKeys = cache2go.GetEntriesKeys(tenantPrfx)
}
if len(alsKeys) == 0 {
if alsKeys, err = rs.db.Keys(tenantPrfx + "*"); err != nil {
return nil, err
}
}
for _, key := range alsKeys {
tenantPrfx := ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
if alsAcnt, err := rs.GetAccAlias(key[len(ACC_ALIAS_PREFIX):], checkDb); err != nil {
if alsAcnt, err := rs.GetAccAlias(key[len(ACC_ALIAS_PREFIX):], skipCache); err != nil {
return nil, err
} else if alsAcnt == account {
alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant
@@ -524,14 +525,7 @@ func (rs *RedisStorage) GetDestination(key string) (dest *Destination, err error
err = rs.ms.Unmarshal(out, dest)
// create optimized structure
for _, p := range dest.Prefixes {
var ids []string
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
ids = x.([]string)
}
if !utils.IsSliceMember(ids, dest.Id) {
ids = append(ids, dest.Id)
}
cache2go.Cache(DESTINATION_PREFIX+p, ids)
cache2go.CachePush(DESTINATION_PREFIX+p, dest.Id)
}
} else {
return nil, errors.New("not found")
@@ -557,13 +551,12 @@ func (rs *RedisStorage) SetDestination(dest *Destination) (err error) {
return
}
func (rs *RedisStorage) GetActions(key string, checkDb bool) (as Actions, err error) {
func (rs *RedisStorage) GetActions(key string, skipCache bool) (as Actions, err error) {
key = ACTION_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(Actions), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(Actions), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -580,13 +573,12 @@ func (rs *RedisStorage) SetActions(key string, as Actions) (err error) {
return
}
func (rs *RedisStorage) GetSharedGroup(key string, checkDb bool) (sg *SharedGroup, err error) {
func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) {
key = SHARED_GROUP_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(*SharedGroup), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(*SharedGroup), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -599,7 +591,7 @@ func (rs *RedisStorage) GetSharedGroup(key string, checkDb bool) (sg *SharedGrou
func (rs *RedisStorage) SetSharedGroup(sg *SharedGroup) (err error) {
result, err := rs.ms.Marshal(sg)
err = rs.db.Set(SHARED_GROUP_PREFIX+sg.Id, result)
cache2go.Cache(SHARED_GROUP_PREFIX+sg.Id, sg)
//cache2go.Cache(SHARED_GROUP_PREFIX+sg.Id, sg)
return
}
@@ -664,13 +656,12 @@ func (rs *RedisStorage) GetAllActionTimings() (ats map[string]ActionPlan, err er
return
}
func (rs *RedisStorage) GetDerivedChargers(key string, checkDb bool) (dcs utils.DerivedChargers, err error) {
func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) {
key = DERIVEDCHARGERS_PREFIX + key
if x, err := cache2go.GetCached(key); err == nil {
return x.(utils.DerivedChargers), nil
}
if !checkDb {
return nil, errors.New(utils.ERR_NOT_FOUND)
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
return x.(utils.DerivedChargers), nil
}
}
var values []byte
if values, err = rs.db.Get(key); err == nil {
@@ -683,6 +674,7 @@ func (rs *RedisStorage) GetDerivedChargers(key string, checkDb bool) (dcs utils.
func (rs *RedisStorage) SetDerivedChargers(key string, dcs utils.DerivedChargers) (err error) {
if len(dcs) == 0 {
_, err = rs.db.Del(DERIVEDCHARGERS_PREFIX + key)
// FIXME: Does cache need cleanup too?
return err
}
marshaled, err := rs.ms.Marshal(dcs)

View File

@@ -104,6 +104,7 @@ func TestCacheRefresh(t *testing.T) {
dataStorage.SetDestination(&Destination{"T11", []string{"0"}})
dataStorage.GetDestination("T11")
dataStorage.SetDestination(&Destination{"T11", []string{"1"}})
t.Log("Test cache refresh")
dataStorage.CacheRating(nil, nil, nil, nil, nil)
d, err := dataStorage.GetDestination("T11")
p := d.containsPrefix("1")

View File

@@ -78,7 +78,7 @@ func (uc *UnitsCounter) addUnits(amount float64, prefix string) {
}
for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]string)
destIds := x.([]interface{})
for _, dId := range destIds {
if dId == mb.DestinationId {
mb.Value += amount

View File

@@ -34,12 +34,12 @@ func IsSliceMember(ss []string, s string) bool {
// Binary string search in slice
// returns true if found and the index
func GetSliceMemberIndex(ss []string, s string) (bool, int) {
func GetSliceMemberIndex(ss []string, s string) (int, bool) {
sort.Strings(ss)
if i := sort.SearchStrings(ss, s); i < len(ss) && ss[i] == s {
return true, i
return i, true
}
return false, len(ss)
return len(ss), false
}
//Iterates over slice members and returns true if one starts with prefix
@@ -51,3 +51,10 @@ func SliceMemberHasPrefix(ss []string, prfx string) bool {
}
return false
}
func ConvertInterfaceSliceToStringSlice(is []interface{}) (result []string) {
for _, i := range is {
result = append(result, i.(string))
}
return result
}