Fork me on GitHub

I’m new to clojure and I’m not familiar with all the asynchronous mechanisms so I’m looking for a little guidance. I have a jdbc query that could take minutes or hours. How do I construct an asynchronous query mechanism? Specifically, I want the function to return immediately and perhaps a callback function for processing the results after the query returns. Is there a function I could call which would take a query as the first argument, execute it on a thread and return and a callback function which will be called when the results of the query return. For example,

(do-async  (jdbc/query db-spec query) :callback (fn [response] (process-response response))))
I’ve been reading the docs for core.async but can’t seem to put it all together in a cohesive way. Any pointers to guides, examples, blog posts or libraries would be appreciated. Thanks!


you likely just want a thread


so use future


if you are coming from a js background, async there is usually synonymous with multiple threads of execution which are achieved by slicing things in to multiple tasks that executed one at a time on a single real thread


the jvm is a multithreaded runtime, so if you want multiple threads of execution, you can just have them


@hiredman Thanks for your help. I’ll read up on thread/future. I have a Java UI background so I’m thinking of a mechanism like SwingWorker


yeah, future


@hiredman I’ve been reading a bit about future and I’m not clear how I can process the results asynchronously. It appears that we must dereference the result (channel?) in order to get the query results and that dereference will block until the function passed into the future is complete. I just want to define a callback function which will be called with the query results when the future task completes. Is there any guidance on that use case?


you don't need a callback


(future (some-function (some-query-function)))


future returns a future (not a channel)


you don't need to deref a future


when you give it stuff to run, it is immediately run on another thread in a threadpool


deref returns the result if of whatever you ran in the future if you want it


I’m not getting the results I’m looking for. It appears that I’ll have to poll the future to determine when it is done and then I can dereference it to extract the value. How can I avoid polling and have the results passed to a function automatically when the future is done?


Sorry. Let me try your suggestion of putting the future on the “callback function”


On a note: JDBC is not asynchronous. The most you can do with it is execute on a different thread so you're original calling thread isn't blocked, which is what future does for you. If you want to run it on a separate thread, and then have a function process the result in the future without polling, you probably want to look into either core.async, manifold, or the simple method that @hiredman suggested of: (future (my-final-result-fn (my-long-running-query)))


I would avoid the two libraries I mentioned until you know you actually need something more complex than the future version


I just did a small experiment and I think the mechanism that @hiredman will work for me. Thank you all for your help and guidance