invoiceregistry: ensure we never send duplicate add/settle notifications
In this commit, we add additional logic to the primary notification dispatch loop to ensure that we'll never send the same add/settle event to the same client twice. Consider the case where as we're sending a client its notification backlog, a new invoice is settled (index=9). In this case, the database will be reflected immediately, and the event will also be queued for notifying later. We'll send out this latest event during the backlog clear, but then will send it again once we return back to the main loop. To ensure that this never happens, we'll now record the last index that we’ve sent to a client to ensure that we no longer are able to send duplicate notification events.
This commit is contained in:
parent
3bedffcc1a
commit
2dcc2d63a6
@ -135,14 +135,45 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
|
||||
// dispatch notifications to all registered clients.
|
||||
case event := <-i.invoiceEvents:
|
||||
for _, client := range i.notificationClients {
|
||||
// Before we dispatch this event, we'll check
|
||||
// to ensure that this client hasn't already
|
||||
// received this notification in order to
|
||||
// ensure we don't duplicate any events.
|
||||
invoice := event.invoice
|
||||
switch {
|
||||
// If we've already sent this settle event to
|
||||
// the client, then we can skip this.
|
||||
case event.isSettle &&
|
||||
client.settleIndex == invoice.SettleIndex:
|
||||
continue
|
||||
|
||||
// Similarly, if we've already sent this add to
|
||||
// the client then we can skip this one.
|
||||
case !event.isSettle &&
|
||||
client.addIndex == invoice.AddIndex:
|
||||
continue
|
||||
}
|
||||
|
||||
select {
|
||||
case client.ntfnQueue.ChanIn() <- &invoiceEvent{
|
||||
isSettle: event.isSettle,
|
||||
invoice: event.invoice,
|
||||
invoice: invoice,
|
||||
}:
|
||||
case <-i.quit:
|
||||
return
|
||||
}
|
||||
|
||||
// Each time we send a notification to a
|
||||
// client, we'll record the latest add/settle
|
||||
// index it has. We'll use this to ensure we
|
||||
// don't send a notification twice, which can
|
||||
// happen if a new event is added while we're
|
||||
// catching up a new client.
|
||||
if event.isSettle {
|
||||
client.settleIndex = invoice.SettleIndex
|
||||
} else {
|
||||
client.addIndex = invoice.AddIndex
|
||||
}
|
||||
}
|
||||
|
||||
case <-i.quit:
|
||||
|
Loading…
Reference in New Issue
Block a user