I’m writing a little clojure pub/sub interface. It’s very barebones, only two methods that will actually be used: do-pub and sub-listen. sub-listen takes a string (a sub name) and do-pub takes two strings (a sub name and a value).
I’m still fairly new at clojure and am having some trouble coming up with a workable way to do this. My first thought (and indeed my first implementation) uses a single agent which holds a hash:
{ subname (promise1 promise2 etc) }
When a thread wants to sub it conj’s a promise object to the list associated with the sub it wants, then immediately tries to de-reference that promise (therefore blocking).
When a pub happens it goes through every item in the list for the sub and delivers the value to that item (the promise). It then dissoc’s that subname from the map and returns it to the agent.
In this way I got a simple pub sub implementation working. However, the problem comes when someone subs, doesn’t receive a pub for a certain amount of time, then gets killed due to timeout. In this scenario there will be a worthless promise in the agent that doesn’t need to be, and moreover this will be a source of a memory leak if that sub never gets pub’d.
Does anyone have any thoughts on how to solve this? Or if there is a better way to do what I’m trying to do overall (I’m trying to avoid using any external pre-cooked pubsub libraries, this is a pet project not a work one)?
You can do something like this:
atompublishfunction will update the atom value by the passed in value to the functionadd-watchon the atom to be notified of when the atom value changes i.e due to call topublishfunctionremove-watchto remove the subscription.This way you will have a very basic pub-sub system.