0

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?

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to tell that the timeout channel is closed and that the loop should be terminated? There isn't a "closed?" function or anything.
alts! returns to you which channel it read from. If that was the timeout channel, then the timeout has expired.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.