@@ -23,9 +23,8 @@ type DatabaseListenerDictionary[T any, PS IPubSubBackend, DB any, C Change[C]] s
2323 // Dictionary for managing the subscriptions by key
2424 subDict * ristretto.Cache [string , * ListenerSubscriptions [T , PS , C ]]
2525
26- get func ([]string ) (map [string ]C , error )
26+ get func (DB , []string ) (map [string ]C , error )
2727 toEvent func (string , Change [C ]) neogate.Event
28- toChange func (neogate.Event ) Change [C ]
2928 createMutex * sync.Mutex
3029 pool * SubPool [PS ]
3130}
@@ -48,7 +47,7 @@ func (ld *DatabaseListenerDictionary[T, PS, DB, C]) channelToKey(channel string)
4847 return values [2 ]
4948}
5049
51- func DictionarySubscribe [T any , PS IPubSubBackend , DB any , C Change [C ], S Subscription [C ]](ld * DatabaseListenerDictionary [T , PS , DB , C ], keys []string , identifier string , subscription S ) error {
50+ func DictionarySubscribe [T any , PS IPubSubBackend , DB any , C Change [C ], S Subscription [C ]](ld * DatabaseListenerDictionary [T , PS , DB , C ], db DB , keys []string , identifier string , subscription S ) error {
5251
5352 // Find all listeners that are not already available
5453 nonCached := []string {}
@@ -66,12 +65,12 @@ func DictionarySubscribe[T any, PS IPubSubBackend, DB any, C Change[C], S Subscr
6665 }
6766
6867 // Create subscriptions so that they can start receiving stuff already
69- return createSubscriptions (ld , keys , identifier , subscription )
68+ return createSubscriptions (ld , db , keys , identifier , subscription )
7069}
7170
7271// Create subscriptions in the ListenerDictionary
7372// TODO(unbreathable): How do we fix broken subscriptions in case an error is returned below subscription creation?
74- func createSubscriptions [T any , PS IPubSubBackend , DB any , C Change [C ], S Subscription [C ]](ld * DatabaseListenerDictionary [T , PS , DB , C ], keys []string , identifier string , subscription S ) error {
73+ func createSubscriptions [T any , PS IPubSubBackend , DB any , C Change [C ], S Subscription [C ]](ld * DatabaseListenerDictionary [T , PS , DB , C ], db DB , keys []string , identifier string , subscription S ) error {
7574 ctx := context .Background ()
7675
7776 toGet := []string {}
@@ -100,7 +99,7 @@ func createSubscriptions[T any, PS IPubSubBackend, DB any, C Change[C], S Subscr
10099 }
101100
102101 // Get the base data for all listeners that were created
103- results , err := ld .Get (toGet )
102+ results , err := ld .Get (db , toGet )
104103 if err != nil {
105104 return fmt .Errorf ("couldn't get from base data: %v" , err )
106105 }
@@ -119,9 +118,41 @@ func createSubscriptions[T any, PS IPubSubBackend, DB any, C Change[C], S Subscr
119118 return nil
120119}
121120
121+ // Reset all values for the keys back to the original value by re-getting them and pushing that update
122+ func (ld * DatabaseListenerDictionary [T , PS , DB , C ]) Reset (db DB , keys []string ) error {
123+ results , err := ld .get (db , keys )
124+ if err != nil {
125+ return err
126+ }
127+
128+ // Build all of the messages for the outbox
129+ messages := make ([]OutboxMessage , len (keys ))
130+ for i , key := range keys {
131+ change , ok := results [key ]
132+ if ! ok {
133+ return fmt .Errorf ("couldn't find result for key %s" , key )
134+ }
135+
136+ // Marshal the event for the reset
137+ event := ld .toEvent (key , change )
138+ bytes , err := sonic .Marshal (event )
139+ if err != nil {
140+ return err
141+ }
142+
143+ messages [i ] = OutboxMessage {
144+ Identifier : ld .keyToChannel (key ),
145+ Data : bytes ,
146+ }
147+ }
148+
149+ // Publish all the messages to the outbox
150+ return ld .outbox .save (db , messages )
151+ }
152+
122153// Get the value for keys from the listener dictionary (makes sure we can add batching in the future)
123- func (ld * DatabaseListenerDictionary [T , PS , DB , C ]) Get (keys []string ) (map [string ]C , error ) {
124- return ld .get (keys )
154+ func (ld * DatabaseListenerDictionary [T , PS , DB , C ]) Get (db DB , keys []string ) (map [string ]C , error ) {
155+ return ld .get (db , keys )
125156}
126157
127158// Handle a change for a specific key
@@ -131,16 +162,28 @@ func (ld *DatabaseListenerDictionary[T, PS, DB, C]) onChange(key string, change
131162 }
132163}
133164
165+ // Package a key and change for the outbox
166+ func (ld * DatabaseListenerDictionary [T , PS , DB , C ]) packageForOutbox (key string , change Change [C ]) (OutboxMessage , error ) {
167+ var message OutboxMessage
168+ bytes , err := sonic .Marshal (change )
169+ if err != nil {
170+ return message , err
171+ }
172+ message = OutboxMessage {
173+ Identifier : ld .keyToChannel (key ),
174+ Data : bytes ,
175+ }
176+ return message , nil
177+ }
178+
134179// Save a change to the outbox, makes sure all of this stays transactional
135180func (ld * DatabaseListenerDictionary [T , PS , DB , C ]) Save (db DB , key string , change Change [C ]) error {
136- event := ld .toEvent (key , change )
137- bytes , err := sonic .Marshal (event )
181+ message , err := ld .packageForOutbox (key , change )
138182 if err != nil {
139183 return err
140184 }
141185
142- return ld .outbox .save (db , OutboxMessage {
143- Identifier : ld .keyToChannel (key ),
144- Data : bytes ,
186+ return ld .outbox .save (db , []OutboxMessage {
187+ message ,
145188 })
146189}
0 commit comments