gpt4 book ai didi

haskell - 保持后台进程在 heroku 上运行

转载 作者:行者123 更新时间:2023-12-04 17:59:56 25 4
gpt4 key购买 nike

我正在尝试在 heroku 上运行 rabbitmq 后台进程以从队列中挑选任务并处理它们。我正在使用 AMQP haskell 库,他们提供以下 example (部分省略或简洁。

main = do
--setup connection omitted
--connect to queue, wait for messages
consumeMsgs chan "myQueue" Ack myCallback
--halts process so messages are taken off the queue until a key is presseed
getLine -- wait for keypress
closeConnection conn -- close connection after key
putStrLn "connection closed"

这在本地工作正常,因为 getLine保持进程运行,直到你按下一个键。但是,当我将其部署到 heroku 时,进程退出并显示

2016-04-19T08:37:23.373087+00:00 app[worker.1]: worker: <stdin>: hGetChar: end of file

我从 the accepted answer to this question 中得出结论这是因为为了通过 ssh 部署后台进程,您需要重定向 /dev/null/stdin它发送一个 EOF向进程发出信号。

在我们的例子中 getLine函数因为这个信号而退出,整个过程停止,防止我们的工作人员熬夜。

我如何在部署时让这个 worker 保持运行?

编辑:最终解决方案使用@carstons 评论我最终得到了以下有效的实现:

main :: IO ()
main = do
mvar <- newEmptyMVar
conn <- setupConnection
queueName <- pack <$> getEnv "QUEUE_NAME"
chan <- openChannel conn
consumeMsgs chan queueName Ack processMessage
installHandler sigINT (Catch (cleanupConnection conn mvar)) Nothing
putStrLn "Running forever, press ctrl c to exit"
-- this blocks until sigint is recieved and the handler for SIGINT
-- "fills" the mvar. once that is filled the process exits
run <- takeMVar mvar
case run of
_ -> return ()

mixpanelConfig :: IO Config
mixpanelConfig = liftM2 Config (ApiToken . pack <$> getEnv "MIXPANEL_API_TOKEN") (newManager tlsManagerSettings)

cleanupConnection :: Connection -> MVar () -> IO ()
cleanupConnection conn mvar = do
closeConnection conn
putStrLn "SIGINT received.. closing rabbitmq connection"
putMVar mvar ()

processMessage :: (Message, Envelope) -> IO ()

最佳答案

正如我在评论中指出的那样,如果你只是想让它永远运行,你可以使用 forever与 - 例如 - threadDelay :

import Control.Concurrent (threadDelay)
import Control.Monad (forever)

main = do
--setup connection omitted
--connect to queue, wait for messages
consumeMsgs chan "myQueue" Ack myCallback
--halts process so messages are taken off the queue forever
forever $ threadDelay 10000
-- so this will never happen and you could remove it
closeConnection conn -- close connection after key
putStrLn "connection closed"

请注意,这当然不会真正关闭连接或退出应用程序 - 您必须终止该进程。


替代方案会涉及更多,因为您需要一些消息/方式来向您的程序发送终止信号。

一个简单的方法是使用 MVar当您的队列收到某个停止消息时,您可以在myCallback 中设置它:

import Control.Concurrent.MVar

main = do
-- MVar to receve the quit-signal
quitSignal <- newEmptyMVar
--setup connection omitted
--connect to queue, wait for messages - the callback should
--set the quitSignal with putMVar quitSignal ()
consumeMsgs chan "myQueue" Ack (myCallback quitSignal)
--halts process so messages are taken off the queue till quitSignal
takeMVar quitSignal
-- so this will happen after quitSignal was set
closeConnection conn -- close connection after key
putStrLn "connection closed"

关于haskell - 保持后台进程在 heroku 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36718177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com