On Thu, 25 Oct 2018 at 21:47, <brj...@gmail.com> wrote: > It seems that I somewhat over-engineered my queue :-) I don't know any > Java so this is very helpful! >
When it comes to Java concurrency, ExecutorService and BlockingQueue cover a lot of bases. > If I want to know the result of the email send within the worker > thread, would you recommend sending it back through a channel? > You can actually get back a return value directly, though it requires a wrapper function: (defn submit [^java.util.concurrent.ExecutorService executor, ^Callable f] (.submit executor f)) (let [executor (java.util.concurrent.Executors/newFixedThreadPool 32)] result (submit executor #(+ 1 1))] (prn @result)) In the above example we're using ".submit" rather than ".execute", which tells the executor we care about the return value from the function and want it back. It returns it as a future, result, which we can deref as @result. When a future is dereferenced in Clojure, the current threat blocks until it's receives a value. The purpose of the "submit" function is to force the executor through type hints to treat the function as a Callable with a return value. I wasn't able to get it working without this wrapper. One purpose of my queue was to be able to put urgent messages at the front > of the queue. I guess that using a threadpool with workers does not give me > any guarantee that the email is delivered immediately, since X emails may > already have been added but not yet sent. I guess that one one use a > dedicated thread(pool) for urgent messages? > Yes, you could do that. You could also use a priority queue with the PriorityBlockingQueue class. A priority queue is a queue with a comparator that allows you to control ordering, shunting certain items to the front. There's a library called Claypoole <https://github.com/TheClimateCorporation/claypoole> that packages all these Java classes into nice Clojure functions, and it includes a priority queue so I'd advise looking into it. I haven't tried it myself, but it looks like you can do something like: (require '[com.climate.claypoole :as cp]) (let [pool (cp/priority-threadpool 32) result1 (cp/future (cp/with-priority pool 1000) (send-email important-mail)) result2 (cp/future (cp/with-priority pool 0) (send-email unimportant-mail))] (prn @result1) (prn @result2)) Which is probably easier than messing around with the executor classes directly. -- James Reeves booleanknot.com -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.