ztellman/lamina

wait-for-result swallows next message on timeout

databu opened this issue · 3 comments

When wait-for-result is called using a call to (read-channel ch) and with a timeout, and does indeed timeout, the next message enqueued in ch seems still to be consumed by it. For example, this code results in a TimeoutException instead of the expected result :m

(let [ch (channel)]
     (try
       (wait-for-result (read-channel ch) 0)
       (catch java.util.concurrent.TimeoutException _ nil))
     (enqueue ch :m)
     (wait-for-result (read-channel ch) 0)) 

In contrast, calling read-channel* instead with a timeout works as expected:

(let [ch (channel)]
     (try
       (wait-for-result (read-channel* ch :timeout 0))
       (catch java.util.concurrent.TimeoutException _ nil))
     (enqueue ch :m)
     (wait-for-result (read-channel* ch :timeout 0)))

This is an easy enough change, but it's not clear to me that specifying a timeout for wait-for-result suggests that the timeout should apply to anything other than the "wait". As you point out, adding a timeout to read-channel causes the read itself to timeout.

Could you expand on why you think this is not "expected" behavior?

FWIW I think it makes more sense for read-channel to still consume the item. Your scenario is like "Read the next item. If it finishes within the next 0 ms, let me know." The read is still pending.

I think you're right about this, I was confused as to how result channels are supposed to work (some doc would be great :) ). What I really want is wait-for-message.