component

Jacob Rosenzweig 2023-10-31T23:22:12.952549Z

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.

seancorfield 2023-10-31T23:24:25.395819Z

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).

Jacob Rosenzweig 2023-10-31T23:35:26.106019Z

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.

seancorfield 2023-10-31T23:42:47.142039Z

I mean that your stop code and enforce-display! need to cooperate so that stop can tell the loop to end.

👍 1
seancorfield 2023-10-31T23:43:47.543689Z

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.

seancorfield 2023-10-31T23:44:49.958289Z

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).

seancorfield 2023-10-31T23:45:28.943899Z

(I'd probably use the promise unless you already have core.async in the mix)

Jacob Rosenzweig 2023-10-31T23:51:55.231819Z

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.