-
Notifications
You must be signed in to change notification settings - Fork 0
/
cacheablemanager.go
143 lines (119 loc) · 3.4 KB
/
cacheablemanager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package gocacheable
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/josemiguelmelo/gocacheable/events"
"github.com/sirupsen/logrus"
gcCacheModule "github.com/josemiguelmelo/gocacheable/cachemodule"
gcInterfaces "github.com/josemiguelmelo/gocacheable/interfaces"
)
// CacheableManager is responsible to manage cache storage
type CacheableManager struct {
Identifier string
modules []gcCacheModule.CacheModule
EventsManager events.CacheEventsManager
}
// NewCacheableManager Create new CacheableManager object without modules
func NewCacheableManager(identifier string) CacheableManager {
return CacheableManager{
Identifier: identifier,
modules: []gcCacheModule.CacheModule{},
}
}
// ModulesCount returns number of modules
func (cs *CacheableManager) ModulesCount() int {
return len(cs.modules)
}
// ContainsModule verifies if manager contains the module with identifier=:identifier
func (cs *CacheableManager) ContainsModule(module gcCacheModule.CacheModule) bool {
for _, m := range cs.modules {
if m.Identifier == module.Identifier {
return true
}
}
return false
}
// AddModule adds a new module if it still does not exists
func (cs *CacheableManager) AddModule(name string, storageProvider gcInterfaces.CacheProviderInterface) error {
err := storageProvider.Init()
if err != nil {
return err
}
module := gcCacheModule.New(name, storageProvider)
if cs.ContainsModule(module) {
return errors.New("Module already exists")
}
cs.modules = append(cs.modules, module)
return nil
}
// FindModule finds a module by its identifier
func (cs *CacheableManager) FindModule(identifier string) (*gcCacheModule.CacheModule, error) {
for _, m := range cs.modules {
if m.Identifier == identifier {
return &m, nil
}
}
return &gcCacheModule.CacheModule{}, errors.New("Module not found")
}
// Get get key value from cache
func (cs *CacheableManager) Get(moduleID string, key string, out interface{}) error {
module, err := cs.FindModule(moduleID)
if err != nil {
return err
}
return module.Get(key, &out)
}
// DeleteKey removes a key from a module
func (cs *CacheableManager) DeleteKey(moduleID string, key string) error {
module, err := cs.FindModule(moduleID)
if err != nil {
return err
}
return module.Delete(key)
}
// Reset resets a module cache
func (cs *CacheableManager) Reset(moduleID string) error {
module, err := cs.FindModule(moduleID)
if err != nil {
return err
}
return module.Reset()
}
// Cacheable adds cache to the function passed as parameter
func (cs *CacheableManager) Cacheable(moduleID string, key string, f func() (interface{}, error), out interface{}, timeToLive time.Duration) error {
module, err := cs.FindModule(moduleID)
if err != nil {
return err
}
if module.IsCacheStorageCreated() {
return errors.New("Cache storage not created")
}
var obj interface{}
// Check on cache and return if found
err = module.Get(key, &out)
if err == nil {
return err
}
time.AfterFunc(timeToLive, func() {
if module.HasKey(key) {
if deleteErr := module.Delete(key); deleteErr != nil {
logrus.Errorln(fmt.Sprintf("Error deleting cache with key = %s from module %s with err = %s", key, module.Name, deleteErr.Error()))
}
}
})
obj, err = f()
if err == nil {
err = module.Set(key, obj)
if err != nil {
return err
}
jsonData, _ := json.Marshal(obj)
err = json.Unmarshal(jsonData, &out)
if err != nil {
return err
}
}
return err
}