diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 8ed7cc75f..d5ee534f4 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -113,7 +113,7 @@ func NewMongoStorage(host, port, db, user, pass, storageType string, cdrsIndexes return nil, err } } - ms.cnter = utils.NewCounterGen(time.Now().UnixNano(), 0) + ms.cnter = utils.NewCounter(time.Now().UnixNano(), 0) return } @@ -125,7 +125,7 @@ type MongoStorage struct { cacheCfg *config.CacheConfig loadHistorySize int cdrsIndexes []string - cnter *utils.CounterGen + cnter *utils.Counter } func (ms *MongoStorage) conn(col string) (*mgo.Session, *mgo.Collection) { diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go index 6ba0110b7..8bde96e9e 100644 --- a/engine/storage_mongo_stordb.go +++ b/engine/storage_mongo_stordb.go @@ -878,7 +878,7 @@ func (ms *MongoStorage) GetSMCosts(cgrid, runid, originHost, originIDPrefix stri func (ms *MongoStorage) SetCDR(cdr *CDR, allowUpdate bool) (err error) { if cdr.OrderID == 0 { - cdr.OrderID = ms.cnter.Gen() + cdr.OrderID = ms.cnter.Next() } session, col := ms.conn(utils.TBLCDRs) defer session.Close() diff --git a/utils/coreutils.go b/utils/coreutils.go index 45ac42777..40935e321 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -40,26 +40,32 @@ import ( "time" ) -func NewCounterGen(start, limit int64) *CounterGen { - return &CounterGen{ - cnt: start, +func NewCounter(start, limit int64) *Counter { + return &Counter{ + value: start, limit: limit, } } -type CounterGen struct { - cnt, limit int64 +type Counter struct { + value, limit int64 sync.Mutex } -func (cg *CounterGen) Gen() int64 { - cg.Lock() - defer cg.Unlock() - cg.cnt += 1 - if cg.limit > 0 && cg.cnt > cg.limit { - cg.cnt = 0 +func (c *Counter) Next() int64 { + c.Lock() + defer c.Unlock() + c.value += 1 + if c.limit > 0 && c.value > c.limit { + c.value = 0 } - return cg.cnt + return c.value +} + +func (c *Counter) Value() int64 { + c.Lock() + defer c.Unlock() + return c.value } // Returns first non empty string out of vals. Useful to extract defaults diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index 0fb4b8cf3..619a8337a 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -20,6 +20,7 @@ package utils import ( "fmt" "reflect" + "sync" "testing" "time" ) @@ -759,3 +760,31 @@ Date: Fri Dec 30 19:48:09 2016 +0100 t.Errorf("Expecting: <%s>, received: <%s>", eVers, vers) } } + +func TestCounter(t *testing.T) { + var nmax int64 = 10000 + ch := make(chan int64, nmax) + wg := new(sync.WaitGroup) + cnter := NewCounter(0, nmax-1) + var i int64 + for i = 1; i <= nmax; i++ { + wg.Add(1) + go func() { + ch <- cnter.Next() + wg.Done() + }() + } + wg.Wait() + m := make(map[int64]bool) + for i = 1; i <= nmax; i++ { + m[<-ch] = true + } + for i = 1; i <= nmax-1; i++ { + if !m[i] { + t.Errorf("Missing value: %d", i) + } + } + if cnter.Value() != 0 { + t.Error("Counter was not reseted to 0") + } +}