core-async

souenzzo 2020-09-03T12:59:59.004600Z

Hey, I'm (still) trying to understand the pipeline-blocking and it's uses: I did a REPL experiment:

(let [stdin (async/chan)
      stdout (async/chan)
      prn2 #(locking prn (prn %))]
  (async/pipeline-blocking 2
                           stdout
                           (map #(doto % prn2))
                           stdin)
  (async/go-loop []
    (when-let [x (async/<! stdout)]
      (prn2 [:stdout x]))
    (prn2 [:close]))
  (dotimes [i 10]
    (prn2 [:put i (async/put! stdin i)]))
  (async/close! stdin))
It behaves: - All 10 put! returns true - Only 5 (the first 5) elements get processed - The stdout only receive 1 processed result, then receive a close - On VisualVM, I see a lot of of "zombie threads" None of these behaviors make sense for me. Where I can read more about it? There is use examples?

alexmiller 2020-09-03T13:47:12.005300Z

put! is async so will basically queue up 10 pending puts (returns true if the channel isn't closed and it's not)

alexmiller 2020-09-03T13:48:30.006600Z

the "zombie" threads are probably not "zombies", they are mostly daemon threads in pools waiting for work and will go away if they don't get any. the go-loop is backed by a pool, and pipeline blocking is backed by a pool, so I'd expect threads from both of those

alexmiller 2020-09-03T13:50:16.007300Z

you're using a transducer but unbuffered in/out channels, that may be an issue, could be an unhandled exception happening there

alexmiller 2020-09-03T13:50:54.008100Z

if you change stdin / stdout to have a buffer (async/chan 10) does that change what you see?

👍 1
souenzzo 2020-09-03T18:41:18.010500Z

@alexmiller I'm trying to implement a "clojure idiomatic" http server, from java SocketServer (for learning/fun) ATM I'm using java.util.concurrent/newFixedThreadPool as thread pool. Does make sense use pipeline-blocking in this case?

2020-09-03T18:45:37.011200Z

pipeline-blocking and pipeline will act like their own additional threadpool, they won't use threads from your threadpool

2020-09-03T18:46:32.012100Z

you can use pipeline-async to run tasks on your own threadpool

souenzzo 2020-09-03T18:46:43.012400Z

Yeah, i'm saying, stop using threadpool and use pipeline

souenzzo 2020-09-03T18:48:00.013500Z

Or they are not "equivalent"? I'm still not understand well the use-case of pipeline-blocking

2020-09-03T18:48:58.014100Z

a pipeline takes inputs, does something to them, and then outputs them, in order

2020-09-03T18:51:47.016300Z

so you could use that to implement processing an http request, but there are a lot of decisions to be made on how to do that

2020-09-03T18:52:51.017300Z

if you are using SocketServer, the example servers for that kind of thing usually spin up a new thread (or put a task on a threadpool) for each request, the analogue of that would be running a go block, not using a pipeline

2020-09-03T18:54:35.018200Z

a pipeline is more like a combination of an executor and a ExecutorCompletionService, with some more bits (combining an executor and an exceutorcompletionservice doesn't get you the ordering you get from a pipeline)

2020-09-03T18:55:24.018600Z

which is to say, a pipeline is not equivalent to an executor

souenzzo 2020-09-07T18:21:06.021200Z

After some interations with @d.ian.b I see that this use-case is more about agent and less about pipeline 😉

1
souenzzo 2020-09-03T19:09:56.018900Z

Tnks @hiredman I will keep at "regular" threadpools One signal that it's not a pipeline blocking problem is that i don't care about "output" I just need to "submit" and get the work done in another thread

2020-09-03T19:15:13.019100Z

A pipeline might work well if you implement http request pipelining or whatever it is called where you re-use the same tcp connection for multiple http requests

2020-09-03T19:16:01.019300Z

So you would process the requests in parallel and return results in order

👍 1
souenzzo 2020-09-03T19:20:59.019800Z

Once I get closer to HTTP/2 or websockets I can think about it 😅

2020-09-03T20:26:04.020Z

well, http2 is a hole other thing, it does true multiplexing, not pipelining