我正在制作一个Messenger bot,我使用Ring作为我的http框架。
有时我想在机器人发送的消息之间应用延迟。我的期望是使用Thread/sleep
是安全的,因为这会使活动线程休眠,而不是整个服务器。是这样,还是应该诉诸clojure/core.async
?
这是我将在没有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...
环形码的链接,在这个意义上的行为是明确的,以及任何其他有关此问题的解释。
答案 0 :(得分:11)
Ring提出这个问题是错误的:ring不是http服务器,而是http服务器的抽象。 ring本身没有固定的线程模型:它真正关心的是你有一个从请求到响应的功能。
真正做出此决定的是您使用的环形适配器。到目前为止,最常见的是ring-jetty-adapter,它是一个jetty http处理程序,通过ring委托给你的函数。并且jetty确实为每个请求都有一个单独的线程,这样你就可以在一个线程中睡觉而不会影响其他线程(但正如另一个答案所述,线程不是免费的,所以你不想经常做这么多)
但是还有其他环形处理程序具有不同的线程模型。例如,aleph包含一个基于netty的环形适配器,它在一个小的有限线程池中使用java.nio作为非阻塞IO;在这种情况下,睡在“请求线程”上是非常具有破坏性的。
答案 1 :(得分:1)
假设您正在讨论处理程序中的代码,Ring中的Thread/sleep
确实会使请求的线程进入休眠状态。如果您有多个请求,则会烧毁昂贵的服务器线程。
Ring块的原因是(非异步)模型基于函数组合,其中一个函数的结果是另一个函数的输出。所以他们必须等待,我可以在我不知道的代码中确切地指出这一点。
将它放在go-block中更好,因为那样你就不会阻塞服务器线程。它可以在您发送消息时返回响应。请注意,您无法使用go块中的结果。
如果您还想要异步响应(不阻塞服务器线程),您可以使用Pedestal。
对于大多数服务器来说,同步处理程序就足够了,但是如果你使用Thread / sleep并想要一个响应,我建议使用异步Ring处理程序或Pedestal或其他框架。