github.com/emitter-io/go/v2@v2.1.0/store.go (about) 1 package emitter 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/eclipse/paho.mqtt.golang/packets" 8 ) 9 10 // In-memory storage implementation 11 type store struct { 12 sync.RWMutex 13 messages map[string]*packet 14 } 15 16 // Response represents a generic response sent by the broker. 17 type Response interface { 18 RequestID() uint16 19 } 20 21 // The control packet with an optional error and a response. 22 type packet struct { 23 packets.ControlPacket 24 callback chan Response 25 } 26 27 // newStore creates a new message storage layer. 28 func newErrorStore() *store { 29 store := &store{ 30 messages: make(map[string]*packet), 31 } 32 return store 33 } 34 35 // Open initializes a MemoryStore instance. 36 func (store *store) Open() {} 37 38 // Put takes a key and a pointer to a Message and stores the message. 39 func (store *store) Put(key string, message packets.ControlPacket) { 40 store.Lock() 41 defer store.Unlock() 42 43 store.messages[key] = &packet{ 44 ControlPacket: message, 45 } 46 } 47 48 // Get takes a key and looks in the store for a matching Message 49 // returning either the Message pointer or nil. 50 func (store *store) Get(key string) packets.ControlPacket { 51 store.RLock() 52 defer store.RUnlock() 53 return store.messages[key] 54 } 55 56 // All returns a slice of strings containing all the keys currently 57 // in the MemoryStore. 58 func (store *store) All() []string { 59 store.RLock() 60 defer store.RUnlock() 61 62 keys := []string{} 63 for k := range store.messages { 64 keys = append(keys, k) 65 } 66 return keys 67 } 68 69 // Del takes a key, searches the MemoryStore and if the key is found 70 // deletes the Message pointer associated with it. 71 func (store *store) Del(key string) { 72 store.Lock() 73 defer store.Unlock() 74 75 m := store.messages[key] 76 if m != nil && m.callback == nil { 77 delete(store.messages, key) 78 } 79 } 80 81 // Close will disallow modifications to the state of the store. 82 func (store *store) Close() {} 83 84 // Reset eliminates all persisted message data in the store. 85 func (store *store) Reset() { 86 store.Lock() 87 defer store.Unlock() 88 store.messages = make(map[string]*packet) 89 } 90 91 // PutCallback adds a callback channel to a message. 92 func (store *store) PutCallback(id uint16) <-chan Response { 93 store.Lock() 94 defer store.Unlock() 95 96 key := outboundKeyFromMID(id) 97 if m, ok := store.messages[key]; ok && m != nil { 98 m.callback = make(chan Response, 1) 99 return m.callback 100 } 101 return nil 102 } 103 104 // NotifyResponse notifies a response on a callback (if exists) 105 func (store *store) NotifyResponse(id uint16, response Response) bool { 106 store.RLock() 107 defer store.RUnlock() 108 109 key := outboundKeyFromMID(id) 110 if m, ok := store.messages[key]; ok && m != nil { 111 m.callback <- response 112 close(m.callback) 113 delete(store.messages, key) 114 return true 115 } 116 return false 117 } 118 119 // Return a string of the form "o.[id]" 120 func outboundKeyFromMID(id uint16) string { 121 return fmt.Sprintf("o.%d", id) 122 }