Skip to content

Instantly share code, notes, and snippets.

@amedeedaboville
Last active June 12, 2022 09:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amedeedaboville/2bc6bc5c9d50f343a46bc6ad3864167f to your computer and use it in GitHub Desktop.
Save amedeedaboville/2bc6bc5c9d50f343a46bc6ad3864167f to your computer and use it in GitHub Desktop.
Avoiding a race condition while joining a message queue
Say we have 4 events, that are linearizable:
A: message published in Channel
B: update ETS table
C: read ETS table
D: subscribe to Channel
If neither of the following conditions happen we get data loss:
1. B before C (we read an up to date application state when joining)
2. D before A (we are subscribed when the message is published to the Channel)
(If both conditions happen we get a duplicate message)
There are 24 permutations of these 4 events. Here they are listed:
good (1 holds, but not 2)
AB CD
AB DC
AD BC
BA CD
BA DC
BC AD
good (2 holds, but not 1)
DC BA
DC AB
DA CB
CD BA
CD AB
CB DA
duplicate message (both hold)
BC DA
BD CA
DA BC
DB AC
DB CA
BD AC
bad (neither holds)
AC BD
AC DB
CA BD
CA DB
CB AD
AD CB
About the bad category:
The only bad ordering with C after D is
AD CB
It has A before B.
So we can program our threads to do C after D, and B before A,
and we should be good.
In english that is subscribe, read the state in one thread
and change the state, then publish in the other
If you guarantee C after D, and B before A, you get the following orderings:
BA DC (condition 1 holds)
DC BA (condition 2 holds)
DB CA (dup)
BD CA (dup)
BD AC (dup)
DB AC (dup)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment