Clojure Ring creates a thread for every request?

I am creating a messenger bot and I am using Ring as my http infrastructure.

Someday I want to apply delays between messages sent by a bot. My guess would be that it is safe to use Thread/sleep

because it will make the active sleep thread rather than the entire server. Is this so, or should I resort to clojure/core.async

?

This is the code I would write without async

:

  (match [reply]

    ; The bot wants to send a message (text, images, videos etc.) after n milliseconds
    [{:message message :delay delay}] 
    (do
      (Thread/sleep interval delay)
      (facebook/send-message sender-id message))
    ; More code would follow...

      

A link to a Ring code where its behavior is clear in this sense will be appreciated like any other with an explanation on the matter.

+3


source to share


2 answers


The ring is the wrong thing to ask this question: ring is not an http server, but rather an abstraction across http servers. the ring itself doesn't have a fixed streaming model: all it really cares about is that you have a function from request to response.

What this really does is deciding which subscriber adapter you are using. By far the most common is a ring attachment adapter, which is a jetty HTTP handler that delegates your function through a ring. And jetty does have one thread for each request, so you can sleep on one thread without affecting the others (but as noted in the other answer, threads aren't free, so you don't want to do a ton of that regularly).



But there are other call handlers with different types of flows. For example, aleph includes a netty-based ring adapter that uses java.nio for non-blocking I / O in a small, limited thread pool; in this case, sleeping on the "stream of requests" is very destructive.

+9


source


Assuming you are talking about the code in the handler, Thread/sleep

Ring makes a thread to request sleep. If you have multiple requests, you burn up expensive server streams.

The reason Ring locks is because the (non-asynchronous) model is based on function composition, where the result of one function is the output for another. So they have to wait where exactly I can define this in code that I don't know.

It is best to use it in a go-block because then you are not blocking server threads. It can return a response while the message is being sent. Note that you cannot use results from a go block.



If you also want to receive the response asynchronously (without blocking the server thread), you can, for example, use Pedestal .

Synchronous handlers are sufficient for most servers, but if you are using Thread / sleeps and want a response, I would recommend using Ring or Pedestal asynchronous handlers or some other infrastructure.

+1


source







All Articles