Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Clojure消息处理/异步、多线程_Multithreading_Asynchronous_Clojure_Io_Idioms - Fatal编程技术网

Multithreading Clojure消息处理/异步、多线程

Multithreading Clojure消息处理/异步、多线程,multithreading,asynchronous,clojure,io,idioms,Multithreading,Asynchronous,Clojure,Io,Idioms,我有一个小型Clojure消费者/发布者,通过RabbitMQ接收消息、处理消息并发送给其他消费者 我已经定义了一个消息处理程序,它在一个单独的线程中处理消息(独立于主线程)。 从下面的代码中可以看出,线程同步地接收和发送消息,所有消息都发生在由lcm/subscribe函数启动的事件循环中 所以,问题是,创建这些同步消息处理程序的N大小线程池的“Clojure方法”是什么?我想非Clojure的方法是通过Java互操作手动生成大量线程 另外,考虑到消息处理不是CPU密集型的,这会加快消息处理速

我有一个小型Clojure消费者/发布者,通过RabbitMQ接收消息、处理消息并发送给其他消费者

我已经定义了一个消息处理程序,它在一个单独的线程中处理消息(独立于主线程)。 从下面的代码中可以看出,线程同步地接收和发送消息,所有消息都发生在由lcm/subscribe函数启动的事件循环中

所以,问题是,创建这些同步消息处理程序的N大小线程池的“Clojure方法”是什么?我想非Clojure的方法是通过Java互操作手动生成大量线程

另外,考虑到消息处理不是CPU密集型的,这会加快消息处理速度吗?考虑到发布比处理花费的时间更多,让这些消息处理程序异步会更好吗

最后,我将如何衡量这些相互竞争的方法的性能(我来自Ruby/Javascript世界,那里没有任何多线程)

注意: 我知道,通过水平扩展和生成更多侦听消息总线的JVM进程可以避免所有这些,但由于应用程序将部署在Heroku上,我希望在每个dyno/进程中使用尽可能多的资源

(defn message-handler
  [ch metadata ^bytes payload]
  (let [msg (json/parse-string (String. payload "UTF-8"))
        processed-message (process msg)] 
    (lb/publish ch "e.events" "" processed-message)))

(defn -main
  [& args]
  (let [conn          (rmq/connect {:uri (System/getenv "MSGQ")})
        ch            (lch/open conn)
        q-name        "q.events.tagger"
        e-sub-name    "e.events.preproc"
        e-pub-name    "e.events"
        routing-key   "tasks.taggify"]
    (lq/declare ch q-name :exclusive false :auto-delete false)
    (le/declare ch e-pub-name "fanout" :durable false)
    (lq/bind ch q-name e-sub-name :routing-key routing-key)
    (.start (Thread. (fn []
                       (lcm/subscribe ch q-name message-handler :auto-ack true))))))

从更基本的角度来说。。。如何重构此代码以支持使用附加参数注册消息处理程序回调,如下所示:

    (.start (Thread. (fn []
                       (lcm/subscribe ch q-name (message-handler pub-name) :auto-ack true))))))
然后以引用方式发布:

    (lb/publish ch pub-name "" processed-message)))
而不是文字:

    (lb/publish ch "e.events" "" processed-message)))

这是一个非常大的话题,你可以考虑把这个问题分成几个不同的问题,但是简洁的回答是:

< p>对于问题的第二部分,你可以使用如下所示的部分应用:

(defn message-handler
  [pub-name ch metadata ^bytes payload]
  (let [msg (json/parse-string (String. payload "UTF-8"))
        processed-message (process msg)] 
    (lb/publish ch pub-name "" processed-message)))



(.start 
  (Thread. 
     (fn []
       (lcm/subscribe ch q-name (partial message-handler e-pub-name) :auto-ack true))))))