4 "github.com/Kovensky/go-fscache"
9 type notification interface{}
11 type intentStruct struct {
13 chs []chan notification
16 type intentMapStruct struct {
18 intentLock sync.Mutex // used by the Intent function
20 m map[string]*intentStruct
23 var intentMap = &intentMapStruct{
24 m: map[string]*intentStruct{},
27 func intentKey(key ...fscache.CacheKey) string {
28 return strings.Join(fscache.Stringify(key...), "-")
31 // Register a channel to be notified when the specified keys are notified.
32 // Returns whether the caller was the first to register intent for the given
35 // Cache checks should be done after registering intent, since it's possible to
36 // register Intent while a Notify is running, and the Notify is done after
38 func (m *intentMapStruct) Intent(ch chan notification, keys ...fscache.CacheKey) bool {
39 key := intentKey(keys...)
42 defer m.intentLock.Unlock()
52 s.chs = append(s.chs, ch)
56 // key might have been deleted while only the struct itself was locked -- recheck
64 // Locks the requested keys and return the locked intentStruct.
66 // The intentStruct can be directly unlocked, or given to Free to also
67 // remove it from the intent map.
68 func (m *intentMapStruct) LockIntent(keys ...fscache.CacheKey) *intentStruct {
72 return m._lockIntent(keys...)
75 func (m *intentMapStruct) _lockIntent(keys ...fscache.CacheKey) *intentStruct {
76 s, ok := m.m[intentKey(keys...)]
85 // Removes the given intent from the intent map and unlocks the intentStruct.
86 func (m *intentMapStruct) Free(is *intentStruct, keys ...fscache.CacheKey) {
93 func (m *intentMapStruct) _free(is *intentStruct, keys ...fscache.CacheKey) {
94 // deletes the key before unlocking, Intent needs to recheck key status
95 delete(m.m, intentKey(keys...))
96 // better than unlocking then deleting -- could delete a "brand new" entry
100 // Notifies and closes all channels that are listening for the specified keys;
101 // also removes them from the intent map.
103 // Should be called after setting the cache.
104 func (m *intentMapStruct) NotifyClose(v notification, keys ...fscache.CacheKey) {
108 is := m._lockIntent(keys...)
109 defer m._free(is, keys...)
114 // Closes all channels that are listening for the specified keys
115 // and removes them from the intent map.
116 func (m *intentMapStruct) Close(keys ...fscache.CacheKey) {
120 is := m._lockIntent(keys...)
121 defer m._free(is, keys...)
126 // Notifies all channels that are listening for the specified keys,
127 // but doesn't close or remove them from the intent map.
128 func (m *intentMapStruct) Notify(v notification, keys ...fscache.CacheKey) {
132 is := m._lockIntent(keys...)
138 // NOTE: does not lock the stuct
139 func (s *intentStruct) Notify(v notification) {
140 for _, ch := range s.chs {
145 // NOTE: does not lock the struct
146 func (s *intentStruct) Close() {
147 for _, ch := range s.chs {
153 // NOTE: does not lock the struct
154 func (s *intentStruct) NotifyClose(v notification) {
155 for _, ch := range s.chs {