Is there anyway I can have a looping process in a component has a freshly updated dependency on every iteration? This is what I have right now for my component:
(defrecord DisplayClient []
component/Lifecycle
(start [this]
(let [config-map (load-config)]
(enforce-display! config-map)
(assoc this :config-map config-map)))
(stop [this]
this)
enforce-display! here is my looping function and it essentially just executes a side effect, waits 10 seconds and recurses. Right now, it has no access to the component itself. I can pass this as a parameter, but I’m pretty sure this will go stale along with any dependency I pass into the component’s constructor after the first function call.You would need to stop the loop in stop and let it restart in start -- and you could pass in this (so it will be fresh and correct on every (re) start).
Would I just use component/stop and then component/start to force a restart in my loop then? I assume I’d let that loop die and then the new loop will be created in the start method.
I mean that your stop code and enforce-display! need to cooperate so that stop can tell the loop to end.
You could use core.async to have a control channel that enforce-display! alts from along with a timeout channel (to handle the sleep). And then stop could put a value on that channel.
Or you could use a promise, set up in start that is assoc'd into this and passed to the loop so that it could do a timed deref on it (and deliver the promise in stop).
(I'd probably use the promise unless you already have core.async in the mix)
I had the same idea using future but a promise or core.async works as well! Honestly, I might be able to avoid this altogether. The one dependency I need to keep “fresh” is a websocket connection and I can just store that in an atom and deref everytime in my loop.
The idea here is that the ws-conn needs to be fresh in case the connection between local client/server dies and needs to restart.