]> git.lizzy.rs Git - go-anidb.git/blob - intent.go
anidb: Return the previously available data if API refresh failed
[go-anidb.git] / intent.go
1 package anidb
2
3 import "sync"
4
5 type intentStruct struct {
6         sync.Mutex
7         chs []chan Cacheable
8 }
9
10 type intentMapStruct struct {
11         sync.Mutex
12         m map[string]*intentStruct
13 }
14
15 var intentMap = &intentMapStruct{
16         m: map[string]*intentStruct{},
17 }
18
19 // Register a channel to be notified when the specified keys are notified.
20 //
21 // Cache checks should be done after registering intent, since it's possible to
22 // register Intent while a Notify is running, and the Notify is done after
23 // setting the cache.
24 func (m *intentMapStruct) Intent(ch chan Cacheable, keys ...cacheKey) bool {
25         key := cachePath(keys...)
26
27         m.Lock()
28         s, ok := m.m[key]
29         if !ok {
30                 s = &intentStruct{}
31                 m.m[key] = s
32         }
33         m.Unlock()
34
35         s.Lock()
36         s.chs = append(s.chs, ch)
37         s.Unlock()
38
39         return ok
40 }
41
42 // Notify all channels that are listening for the specified keys.
43 //
44 // Should be called after setting the cache.
45 func (m *intentMapStruct) Notify(v Cacheable, keys ...cacheKey) {
46         key := cachePath(keys...)
47
48         m.Lock()
49         defer m.Unlock()
50         s, ok := m.m[key]
51         if !ok {
52                 return
53         }
54
55         s.Lock()
56         defer s.Unlock()
57
58         for _, ch := range s.chs {
59                 go func(c chan Cacheable) { c <- v }(ch)
60         }
61
62         delete(m.m, key)
63 }