clj-commons / manifold

A compatibility layer for event-driven abstractions
1.02k stars 106 forks source link

`s/take!` sometimes blocking? #193

Closed nivekuil closed 3 years ago

nivekuil commented 3 years ago

My profiling tells me that (s/take! stream) is sometimes taking 70-100ms. Same with (s/try-take!) with a timeout, where the timeout seems to be ignored. stream is created by (s/stream) and connected to a source created by iterator-seq, which is a clojure.lang.LazySeq. I'm unsure where to start debugging this; could someone point me in the right direction? I don't even know if this is something weird I'm doing or a bug given that the docstrings say Guaranteed to be non-blocking.

KingMob commented 3 years ago

@nivekuil Can you post more details on what you're trying to do?

In particular, take! and try-take! are non-blocking, because they return a deferred. However, derefing that deferred to get the underlying value will block if the value isn't ready. It depends on what the iterator is iterating over here. If you're iterating over the results of a bunch of network calls, it might be a while.

Regardless, for try-take!, the deferred should always be realized after the timeout expires. If not, that's a bug.

nivekuil commented 3 years ago

I don't remember the exact use case anymore, but there was no deref-ing involved. Profiling told me that the bare take! call to get the deferred, representing some network call, was itself blocking occasionally.

KingMob commented 3 years ago

Well, if you can dig up the code, I'd like to take a look. If not, mind if I close the issue for now?