Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8509955
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T03:34:29+00:00 2026-06-11T03:34:29+00:00

I’m using a Clojure application to access data from a web API. I’m going

  • 0

I’m using a Clojure application to access data from a web API. I’m going to be making a lot of requests, and many of the requests will lead to more requests being made, so I want to keep the request URLs in a queue that will leave 60 seconds between subsequent downloads.

Following this blog post I put this together:

(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))

If I include a (future (process-queue-item (take! my-queue))) in my code somewhere then at the REPL I can (offer! my-queue "something") and I see the “>> something” printed immediately. So far so good! But I need the queue to last for the entire time my program is active. The (future ...) call I just mentioned works to pull one item out of the queue, once it’s available, but I want something that will watch the queue continually and call process-queue-item whenever something is available.

Also, contrary to the usual Clojure love for concurrency, I want to ensure that only one request is being made at a time and that my program waits 60 seconds to make each subsequent request.

I think this Stack Overflow question is relevant, but I’m not sure how to adapt it to do what I want. How do I poll my queue continuously and ensure that only one request is being run at once?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T03:34:30+00:00Added an answer on June 11, 2026 at 3:34 am

    I ended up rolling my own small library, which I called simple-queue. You can read the full documentation on GitHub, but here is the source in its entirety. I’m not going to keep this answer updated, so if you’d like to use this library please get the source from GitHub.

    (ns com.github.bdesham.simple-queue)
    
    (defn new-queue
      "Creates a new queue. Each trigger from the timer will cause the function f
      to be invoked with the next item from the queue. The queue begins processing
      immediately, which in practice means that the first item to be added to the
      queue is processed immediately."
      [f & opts]
      (let [options (into {:delaytime 1}
                          (select-keys (apply hash-map opts) [:delaytime])),
            delaytime (:delaytime options),
            queue {:queue (java.util.concurrent.LinkedBlockingDeque.)},
            task (proxy [java.util.TimerTask] []
                   (run []
                     (let [item (.takeFirst (:queue queue)),
                           value (:value item),
                           prom (:promise item)]
                       (if prom
                         (deliver prom (f value))
                         (f value))))),
            timer (java.util.Timer.)]
        (.schedule timer task 0 (int (* 1000 delaytime)))
        (assoc queue :timer timer)))
    
    (defn cancel
      "Permanently stops execution of the queue. If a task is already executing
      then it proceeds unharmed."
      [queue]
      (.cancel (:timer queue)))
    
    (defn process
      "Adds an item to the queue, blocking until it has been processed. Returns
      (f item)."
      [queue item]
      (let [prom (promise)]
        (.offerLast (:queue queue)
                    {:value item,
                     :promise prom})
        @prom))
    
    (defn add
      "Adds an item to the queue and returns immediately. The value of (f item) is
      discarded, so presumably f has side effects if you're using this."
      [queue item]
      (.offerLast (:queue queue)
                  {:value item,
                   :promise nil}))
    

    An example of using this queue to return values:

    (def url-queue (q/new-queue slurp :delaytime 30))
    (def github (q/process url-queue "https://github.com"))
    (def google (q/process url-queue "http://www.google.com"))
    

    The calls to q/process will block so that there will be a 30-second delay between the two def statements.

    An example of using this queue purely for side effects:

    (defn cache-url
      [{url :url, filename :filename}]
      (spit (java.io.File. filename)
            (slurp url)))
    
    (def url-queue (q/new-queue cache-url :delaytime 30))
    (q/add url-queue {:url "https://github.com",
                      :filename "github.html"})    ; returns immediately
    (q/add url-queue {:url "https://google.com",
                      :filename "google.html"})    ; returns immediately
    

    Now the calls to q/add return immediately.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Has anyone tried implementing a web application with Clojure ( using Compojure ) and
I am using Clojure/Ring/Compojure-0.4/Enlive stack to build a web application. Are there functions in
I am writing a Desktop GUI application in Clojure using Java Swing. Normally when
I'm using proxy to extend various Swing classes in a Clojure GUI application, generally
I'm building a Clojure Noir web application to run as a WAR file in
I am using Leiningen in my Clojure project (a GUI application) and created a
I'm writing a clojure application which is growing from small to medium sized. We're
We are starting to create an application using JavaScript and HTML5 which will use
I'm trying to implement an application using node.js and other related technologies. Heading from
I have one web application made using MVC3 Razor. Application starts properly in browser

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.