mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 10:36:24 +05:00
193 lines
4.8 KiB
Go
193 lines
4.8 KiB
Go
/*
|
|
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
|
Copyright (C) ITsysCOM GmbH
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
package engine
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/cgrates/cgrates/config"
|
|
"github.com/cgrates/cgrates/utils"
|
|
"github.com/cgrates/ltcache"
|
|
)
|
|
|
|
var Cache *ltcache.TransCache
|
|
|
|
func init() {
|
|
InitCache(nil)
|
|
}
|
|
|
|
var precachedPartitions = []string{
|
|
utils.CacheDestinations,
|
|
utils.CacheReverseDestinations,
|
|
utils.CacheRatingPlans,
|
|
utils.CacheRatingProfiles,
|
|
utils.CacheLCRRules,
|
|
utils.CacheActions,
|
|
utils.CacheActionPlans,
|
|
utils.CacheAccountActionPlans,
|
|
utils.CacheActionTriggers,
|
|
utils.CacheSharedGroups,
|
|
utils.CacheAliases,
|
|
utils.CacheReverseAliases,
|
|
utils.CacheDerivedChargers,
|
|
utils.CacheResourceProfiles,
|
|
utils.CacheResources,
|
|
utils.CacheEventResources,
|
|
utils.CacheTimings,
|
|
utils.CacheStatQueueProfiles,
|
|
utils.CacheStatQueues,
|
|
utils.CacheThresholdProfiles,
|
|
utils.CacheThresholds,
|
|
utils.CacheFilters,
|
|
utils.CacheSupplierProfiles,
|
|
utils.CacheAttributeProfiles,
|
|
}
|
|
|
|
// InitCache will instantiate the cache with specific or default configuraiton
|
|
func InitCache(cfg config.CacheConfig) {
|
|
if cfg == nil {
|
|
cfg = config.CgrConfig().CacheCfg()
|
|
}
|
|
Cache = ltcache.NewTransCache(cfg.AsTransCacheConfig())
|
|
}
|
|
|
|
// NewCacheS initializes the Cache service
|
|
func NewCacheS(cfg *config.CGRConfig, dm *DataManager) (c *CacheS) {
|
|
InitCache(cfg.CacheCfg()) // to make sure we start with correct config
|
|
c = &CacheS{cfg: cfg, dm: dm,
|
|
pcItems: make(map[string]chan struct{})}
|
|
for cacheID := range cfg.CacheCfg() {
|
|
if !utils.IsSliceMember(precachedPartitions, cacheID) {
|
|
continue
|
|
}
|
|
c.pcItems[cacheID] = make(chan struct{})
|
|
}
|
|
return
|
|
}
|
|
|
|
// CacheS deals with cache preload and other cache related tasks/APIs
|
|
type CacheS struct {
|
|
cfg *config.CGRConfig
|
|
dm *DataManager
|
|
pcItems map[string]chan struct{} // signal precaching
|
|
}
|
|
|
|
// GetChannel returns the channel used to signal precaching
|
|
func (chS *CacheS) GetPrecacheChannel(chID string) chan struct{} {
|
|
return chS.pcItems[chID]
|
|
}
|
|
|
|
// Precache loads data from DataDB into cache at engine start
|
|
func (chS *CacheS) Precache() (err error) {
|
|
for cacheID, cacheCfg := range chS.cfg.CacheCfg() {
|
|
if !utils.IsSliceMember(precachedPartitions, cacheID) {
|
|
continue
|
|
}
|
|
if cacheCfg.Precache {
|
|
if err = chS.dm.CacheDataFromDB(
|
|
utils.CacheInstanceToPrefix[cacheID], nil,
|
|
false); err != nil {
|
|
return
|
|
}
|
|
}
|
|
close(chS.pcItems[cacheID])
|
|
}
|
|
return
|
|
}
|
|
|
|
type ArgsGetCacheItemIDs struct {
|
|
CacheID string
|
|
ItemIDPrefix string
|
|
}
|
|
|
|
func (chS *CacheS) V1GetItemIDs(args *ArgsGetCacheItemIDs,
|
|
reply *[]string) (err error) {
|
|
if itmIDs := Cache.GetItemIDs(args.CacheID, args.ItemIDPrefix); len(itmIDs) == 0 {
|
|
return utils.ErrNotFound
|
|
} else {
|
|
*reply = itmIDs
|
|
}
|
|
return
|
|
}
|
|
|
|
type ArgsGetCacheItem struct {
|
|
CacheID string
|
|
ItemID string
|
|
}
|
|
|
|
func (chS *CacheS) V1HasItem(args *ArgsGetCacheItem,
|
|
reply *bool) (err error) {
|
|
*reply = Cache.HasItem(args.CacheID, args.ItemID)
|
|
return
|
|
}
|
|
|
|
func (chS *CacheS) V1GetItemExpiryTime(args *ArgsGetCacheItem,
|
|
reply *time.Time) (err error) {
|
|
if expTime, has := Cache.GetItemExpiryTime(args.CacheID, args.ItemID); !has {
|
|
return utils.ErrNotFound
|
|
} else {
|
|
*reply = expTime
|
|
}
|
|
return
|
|
}
|
|
|
|
func (chS *CacheS) V1RemoveItem(args *ArgsGetCacheItem,
|
|
reply *string) (err error) {
|
|
Cache.Remove(args.CacheID, args.ItemID, true, utils.NonTransactional)
|
|
*reply = utils.OK
|
|
return
|
|
}
|
|
|
|
func (chS *CacheS) V1Clear(cacheIDs []string,
|
|
reply *string) (err error) {
|
|
Cache.Clear(cacheIDs)
|
|
*reply = utils.OK
|
|
return
|
|
}
|
|
|
|
func (chS *CacheS) V1GetCacheStats(cacheIDs []string,
|
|
rply *map[string]*ltcache.CacheStats) (err error) {
|
|
cs := Cache.GetCacheStats(cacheIDs)
|
|
*rply = cs
|
|
return
|
|
}
|
|
|
|
func (chS *CacheS) V1PrecacheStatus(cacheIDs []string, rply *map[string]string) (err error) {
|
|
if len(cacheIDs) == 0 {
|
|
for _, cacheID := range precachedPartitions {
|
|
cacheIDs = append(cacheIDs, cacheID)
|
|
}
|
|
}
|
|
pCacheStatus := make(map[string]string)
|
|
for _, cacheID := range cacheIDs {
|
|
if _, has := chS.pcItems[cacheID]; !has {
|
|
return fmt.Errorf("unknown cacheID: %s", cacheID)
|
|
}
|
|
select {
|
|
case <-chS.GetPrecacheChannel(cacheID):
|
|
pCacheStatus[cacheID] = utils.MetaReady
|
|
default:
|
|
pCacheStatus[cacheID] = utils.MetaPrecaching
|
|
}
|
|
}
|
|
*rply = pCacheStatus
|
|
return
|
|
}
|