I have a function which processes a stream of values from a shared channel and looks for a value which satisfies a specific predicate:
(defn find-my-object [my-channel]
(go-loop []
(when-some [value (<! my-channel)]
(if (some-predicate? value)
value
(recur)
Now I want this function to return some 'failure' value after waiting for a timeout, which I have implemented like this:
(alts! [(find-my-object my-channel) (timeout 1000)])
The problem with this is that the go-loop above continues to execute after the timeout. I want find-my-object
to drain values from my-channel
while the search is ongoing, but I don't want to close my-channel
on timeout, since it's used in some other places. What is the idiomatic way to implement this functionality?
Read from the timeout channel inside of find-my-object
, not outside of it. You can hardcode that if you like, or make the function take a second channel argument, which is the "please stop reading things" channel. Then you can pass it a timeout channel to get the behavior you want now, or pass it some other kind of channel to control it in a different way.