Search code examples
multithreadingasynchronouswebclojure

How to process concurrent user requests in Clojure?


I'm a beginner in Clojure and I am interested in how to process concurrent user requests in a web application. As a node.js developer, I use an event loop (promises/callback/async-await) to access the database to process concurrent user requests, which means the main thread won't be blocked and I can process other users' requests without waiting for a database response. How I can process concurrent user requests in Clojure if I make a request to the database, that means my thread would be blocked and I can't process any other user requests? Should I create a new thread for each user to process requests? I know that I can use futures in Clojure to create a new thread, but how can I use it for example with one request to DB, if create a new thread my main thread will be blocked to wait for a child thread which requests the database? I don't understand how futures can help me in this situation. What is the best practice or maybe servers such as Jetty provide better processing out of the box? I would be very grateful if you can help me in this matter.


Solution

  • The short answer is that a typical Java web server uses many threads in its implementation, some of which are assigned for use by application code when processing requests. At any instant in time, several user requests may be in-flight. There is usually an application thread pool dedicated for application code, managed by the web server.

    As a Clojure application developer, there is nothing to do to make use of the application thread pool. You do not need to write code to allocate new threads. Your web application will automatically be handling concurrent user requests, in distinct threads managed by the web server. There may be some configuration available, depending on the web server library you use. For example, ring-jetty-adapter has options to control the number of threads in the thread pool.

    There are Clojure libraries available which enable asynchronous processing, a model which will be very familiar to you as a node.js developer. To be honest though, async is not the first tool a beginner should reach for as making good use of the existing concurrency features in Java web severs (i.e. thread pools) is often sufficient for handling hundreds of concurrent requests.

    The most well known Clojure async libraries are core.async, manifold, promesa and more recently missionary.