Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Perhaps you could use the <code>seque</code> function? Quoting <code>(doc seque)</code>:</p> <pre><code>clojure.core/seque ([s] [n-or-q s]) Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer. </code></pre> <p>What I have in mind is a lazy sequence getting queue items over the network; you'd wrap this in <code>seque</code>, put that in a Ref and have worker Agents consume items off of this <code>seque</code>. <code>seque</code> returns something which looks just like a regular seq from the point of view of your code, with the queue magic happening in a transparent way. Note that if the sequence you put inside is chunked, then it'll still be forced a chunk at a time. Also note that the initial call to <code>seque</code> itself seems to block until an initial item or two is obtained (or a chunk, as the case may be; I think that's more to do with the way lazy sequences work than <code>seque</code> itself, though).</p> <p>A sketch of the code (a <em>really</em> sketchy one, not tested at all):</p> <pre><code>(defn get-queue-items-seq [] (lazy-seq (cons (get-queue-item) (get-queue-items-seq)))) (def task-source (ref (seque (get-queue-items-seq)))) (defn do-stuff [] (let [worker (agent nil)] (if-let [result (dosync (when-let [task (first @task-source)] (send worker (fn [_] (do-stuff-with task)))))] (do (await worker) ;; maybe do something with worker's state (do-stuff))))) ;; continue working (defn do-lots-of-stuff [] (let [fs (doall (repeatedly 20 #(future (do-stuff))))] fs))) </code></pre> <p>Actually you'd probably want a more complex producer of the queue item seq so that you can ask it to stop producing new items (a necessity if the whole thing is to be able to be shut down gracefully; the futures will die when the task source runs dry, use <code>future-done?</code> to see if they've done so already). And that's just something I can see at first glance... I'm sure there's more things to polish here. I think that the general approach would work, though.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload