在Hedis文档中,给出了一个使用pubSub
函数的示例:
pubSub :: PubSub -> (Message -> IO PubSub) -> Redis ()
pubSub (subscribe ["chat"]) $ \msg -> do
putStrLn $ "Message from " ++ show (msgChannel msg)
return $ unsubscribe ["chat"]
如果pubSub
返回一个Redis ()
,那么是否可以在代码中更深入地从回调之外重用这个msg
消息?
我从一个运行在pubSub
monad中的Scotty端点调用ScottyM
,并且应该返回一个json msg
(长话短说)
myEndpoint :: ScottyM ()
myEndpoint =
post "/hello/world" $ do
data :: MyData <- jsonData
runRedis redisConn $ do
pubSub (subscribe ["channel"]) $ \msg -> do
doSomethingWith msg
return $ unsubscribe ["channel"]
-- how is it possible to retrieve `msg` from here?
json $ somethingBuiltFromMsg
或者,是否有一种在回调中使用Scotty的json
的方法?到目前为止我还没能做到这一点。
发布于 2021-06-07 15:25:58
我将假设您打算进一步缩进json
的行。
您可以在IO
中使用可变变量,例如IORef
import Data.IORef (newIORef, writeIORef, readIORef)
import Control.Monad.IO.Class (liftIO)
myEndpoint :: ScottyM ()
myEndpoint =
post "/hello/world" $ do
data :: MyData <- jsonData
msgRef <- liftIO (newIORef Nothing)
runRedis redisConn $ do
pubSub (subscribe ["channel"]) $ \msg -> do
writeIORef msgRef (Just msg)
return $ unsubscribe ["channel"]
Just msg <- liftIO (readIORef msgRef)
json $ doSomethingWithMsg msg
编辑:我想在收到消息之前,我不知道runRedis函数是否会阻塞,如果不是这样,那么您可以使用MVar
:
import Control.Concurrent.MVar (putMVar, takeMVar, newEmptyMVar)
import Control.Monad.IO.Class (liftIO)
myEndpoint :: ScottyM ()
myEndpoint =
post "/hello/world" $ do
data :: MyData <- jsonData
msgVar <- liftIO newEmptyMVar
runRedis redisConn $ do
pubSub (subscribe ["channel"]) $ \msg -> do
putMVar msgVar msg
return $ unsubscribe ["channel"]
msg <- liftIO (takeMVar msgVar)
json $ doSomethingWithMsg msg
https://stackoverflow.com/questions/67873986
复制相似问题