mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 14:19:54 +05:00
working version for cache transactions
This commit is contained in:
@@ -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})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -35,7 +35,7 @@ const (
|
||||
RECURSION_MAX_DEPTH = 3
|
||||
MIN_PREFIX_MATCH = 1
|
||||
FALLBACK_SUBJECT = utils.ANY
|
||||
DEBUG = false
|
||||
DEBUG = true
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user