clj-commons/claypoole

Timeout ?

aphsa opened this issue · 1 comments

aphsa commented

Is it possible to specify per thread timeout with claypoole/pmap?

Well, not exactly, but there are some workarounds. The issue is that claypoole is just a nice wrapper around built-in Java stuff, and that Java stuff doesn't have per-thread timeouts. But there's some related functionality you could use.

You can't timeout futures, but you can timeout the deref.

(let [f (future ...)
      ;; deref takes a timeout
      result (deref f 1000 :timeout)]
  ;; If you really want to stop that work, you can cancel the future,
  ;; which throws some sort of exception in the thread
  ;; (I think java.util.concurrent.CancellationException?)
  (when (= result :timeout) (future-cancel f)))

You can also shutdown a claypoole threadpool. That won't stop work that's already going on, but it'll stop additional tasks from starting.

(let [p (cp/threadpool 10)
      work (cp/pfor ...)]
  (Thread/sleep 1000)
  (cp/shutdown! p)
  ;; so the threadpool will only do as much as it was able to start in 1s.
  ;; but if each task takes a long time, it could keep running for a while.
)
;; you can also do it with with-shutdown!
(cp/with-shutdown! [p 10]
  (let [res (cp/pmap p ...)]
    (Thread/sleep 1000)
    res))

I hope one of those works for you. And if you know more than I do about the underlying Java concurrency primitives and can make the timeouts you want, I'd be happy to receive a pull request!