【发布时间】:2012-09-12 01:02:22
【问题描述】:
我正在使用 Clojure 应用程序从 Web API 访问数据。我将发出大量请求,其中许多请求会导致发出更多请求,因此我希望将请求 URL 保留在队列中,以便在后续下载之间留出 60 秒。
按照this blog post我把这个放在一起:
(def queue-delay (* 1000 60)) ; one minute
(defn offer!
[q x]
(.offerLast q x)
q)
(defn take!
[q]
(.takeFirst q))
(def my-queue (java.util.concurrent.LinkedBlockingDeque.))
(defn- process-queue-item
[item]
(println ">> " item) ; this would be replaced by downloading `item`
(Thread/sleep queue-delay))
如果我在代码中的某处包含(future (process-queue-item (take! my-queue))),那么在REPL 中我可以(offer! my-queue "something") 并立即看到“>> something”打印出来。到目前为止,一切都很好!但是我需要队列在我的程序处于活动状态的整个过程中持续存在。我刚才提到的(future ...) 调用可以将一个项目从队列中拉出,一旦它可用,但我想要一些能够持续观察队列并在有可用时调用process-queue-item。
另外,与 Clojure 对并发的通常喜爱相反,我想确保一次只发出一个请求,并且我的程序等待 60 秒以发出每个后续请求。
我认为this Stack Overflow question 是相关的,但我不确定如何调整它来做我想做的事。如何连续轮询我的队列并确保一次只运行一个请求?
【问题讨论】:
-
为什么要连续轮询,但每 60 秒才发送一次?每 60 秒轮询一次会完成同样的事情吗?
-
@mamboking 差不多,是的。这种方法的唯一缺点是将第一个项目添加到队列中:如果程序需要 5 秒钟来确定第一个请求 URL 将是什么,那么它将在那里等待 55 秒,直到检查队列。无论如何,该程序将运行很长时间,所以我想这不是什么大问题。
-
您是否避免使用任务调度程序?例如,github.com/zcaudate/cronj(在该 repo 的自述文件中还有其他库的列表)
-
@georgek 我不一定要避免这样的事情,尽管这对我的应用程序来说似乎有点矫枉过正。