/
MemoryStateStore.go
157 lines (134 loc) · 4.08 KB
/
MemoryStateStore.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package state
import (
"time"
cconf "github.com/pip-services3-go/pip-services3-commons-go/config"
"github.com/pip-services3-go/pip-services3-commons-go/errors"
)
// State store that keeps states in the process memory.
//
// Remember: This implementation is not suitable for synchronization of distributed processes.
//
// ### Configuration parameters ###
//
// options:
// - timeout: default caching timeout in milliseconds (default: disabled)
//
// ### Example ###
//
// store := NewMemoryStateStore();
// value := store.Load("123", "key1");
// ...
// store.Save("123", "key1", "ABC");
//
type MemoryStateStore struct {
states map[string]interface{}
timeout int64
}
// Creates a new instance of the state store.
func NewEmptyMemoryStateStore() *MemoryStateStore {
return &MemoryStateStore{
states: make(map[string]interface{}),
timeout: 0,
}
}
// Configures component by passing configuration parameters.
// - config configuration parameters to be set.
func (c *MemoryStateStore) Configure(config *cconf.ConfigParams) {
c.timeout = config.GetAsLongWithDefault("options.timeout", c.timeout)
}
// Clears component state.
func (c *MemoryStateStore) cleanup() {
if c.timeout == 0 {
return
}
cutOffTime := time.Now().UTC().UnixNano() - c.timeout
// Cleanup obsolete entries
for prop := range c.states {
// Remove obsolete entry
if entry, ok := c.states[prop].(*StateEntry); ok && entry.GetLastUpdateTime() < cutOffTime {
delete(c.states, prop)
}
}
}
// Loads stored value from the store using its key.
// If value is missing in the store it returns nil.
//
// - correlationId (optional) transaction id to trace execution through call chain.
// - key a unique state key.
// Returns the state value or <code>nil</code> if value wasn't found.
func (c *MemoryStateStore) Load(correlationId string, key string) interface{} {
if len(key) == 0 {
panic(errors.NewError("Key cannot be empty"))
}
// Cleanup the stored states
c.cleanup()
// Get entry from the store
entry, ok := c.states[key].(*StateEntry)
// Store has nothing
if !ok || entry == nil {
return nil
}
return entry.GetValue()
}
// Loads an array of states from the store using their keys.
//
// - correlationId (optional) transaction id to trace execution through call chain.
// - keys unique state keys.
// Returns an array with state values.
func (c *MemoryStateStore) LoadBulk(correlationId string, keys []string) []*StateValue {
// Cleanup the stored states
c.cleanup()
result := make([]*StateValue, 0)
for _, key := range keys {
value := c.Load(correlationId, key)
result = append(result, &StateValue{Key: key, Value: value})
}
return result
}
// Saves state into the store
//
// - correlationId (optional) transaction id to trace execution through call chain.
// - key a unique state key.
// - value a state value to store.
// Returns The value that was stored in the cache.
func (c *MemoryStateStore) Save(correlationId string, key string, value interface{}) interface{} {
if len(key) == 0 {
panic(errors.NewError("Key cannot be empty"))
}
// Cleanup the stored states
c.cleanup()
// Get the entry
entry, ok := c.states[key].(*StateEntry)
// Shortcut to remove entry from the cache
if value == nil {
delete(c.states, key)
return value
}
// Update the entry
if ok && entry != nil {
entry.SetValue(value)
} else { // Or create a new entry
entry = NewStateEntry(key, value)
c.states[key] = entry
}
return value
}
// Deletes a state from the store by its key.
//
// - correlationId (optional) transaction id to trace execution through call chain.
// - key a unique state key.
func (c *MemoryStateStore) Delete(correlationId string, key string) interface{} {
if len(key) == 0 {
panic(errors.NewError("Key cannot be empty"))
}
// Cleanup the stored states
c.cleanup()
// Get the entry
entry, ok := c.states[key].(*StateEntry)
// Remove entry from the cache
if ok && entry != nil {
delete(c.states, key)
return entry.GetValue()
}
return nil
}