haskell - 如何在同一个函数中订阅多个 Redis channel ?

标签 haskell redis

运行 Redis 3.2.1 和最新的 Hedis 库,我有以下发布程序:

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Database.Redis
import Control.Monad
import Control.Concurrent
import Control.Monad.Trans
import Data.ByteString as BS
import System.Posix.Process
import Data.String.Conv

main :: IO ()
main = do
  conn <- connect defaultConnectInfo
  runRedis conn run

run = do
    liftIO $ threadDelay $ 1000 * 1000
    pid <- liftIO getProcessID
    publish "chan1" (toS $ show pid)
    publish "chan2" (toS $ show pid)
    liftIO $ Prelude.putStrLn "\n\n%%%%%%%\n\nnext\n\n%%%%%%%%\n\n"
    run

订阅者看起来像这样:

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Database.Redis

main :: IO ()
main = do
  conn <- connect defaultConnectInfo
  runRedis conn $ do
    pubSub (subscribe ["chan1"]) $ \msg -> do
      putStrLn $ "chan1 " ++ show (msgChannel msg) ++ ": " ++ show (msgMessage msg)
      return mempty
    pubSub (subscribe ["chan2"]) $ \msg -> do
      putStrLn $ "chan2" ++ show (msgChannel msg) ++ ": " ++ show (msgMessage msg)
      return mempty

输出是:

%%%%%%%

next

%%%%%%%%

chan1 "chan1": "21542"

%%%%%%%

next

%%%%%%%%

chan1 "chan1": "21542"

%%%%%%%

next

%%%%%%%%

chan1 "chan1": "21542"

%%%%%%%

next

%%%%%%%%

现在,看起来只要订阅者阅读了第一个 channel ,就不会阅读发送到第二个 channel 的消息。换句话说,似乎只是忽略了订阅 chan2 的命令。

为了完整起见,这是我的 Cabal 文件:

name:                pub-sub-exp
version:             0.1.0.0
synopsis:            Simple project template from stack
description:         Please see README.md
homepage:            https://github.com/githubuser/pub-sub-exp#readme
license:             BSD3
license-file:        LICENSE
author:              Author name here
maintainer:          example@example.com
copyright:           2016 Author name here
category:            Web
build-type:          Simple
cabal-version:       >=1.10

executable pub
  hs-source-dirs:      src
  main-is:             Pub.hs
  default-language:    Haskell2010
  build-depends:       base >= 4.7 && < 5,
                       hedis,
                       mtl,
                       bytestring,
                       unix,
                       string-conv

executable sub
  hs-source-dirs:      src
  main-is:             Sub.hs
  default-language:    Haskell2010
  build-depends:       base >= 4.7 && < 5,
                       hedis,
                       mtl,
                       bytestring

我正在使用 stack-lts-6.6


为了澄清,我希望订阅者指明消息已发送到 channel 1 和 2。

这是 Redis 的一个众所周知的属性吗?我是否遗漏了一些 Haskell 陷阱?

最佳答案

您需要一次订阅两个 channel 。

pubSub (subscribe ["chan1", "chan2"]) $ \msg -> do

Hedis 没有接通您对 pubSub 的第二次调用。从pubSub's definition可以看出除非订阅计数和未决消息都被耗尽,否则该函数不会返回。另请注意,没有 fork 或其他启用并发的方法。

关于haskell - 如何在同一个函数中订阅多个 Redis channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38228263/

相关文章:

haskell - QuasiQuote 带参数

haskell - 如何让 WebDriver 在 Haskell 的 Mac 上工作?

c++ - 在 Haskell 中删除对象时调用函数

javascript - socket.io 连接多个进程

scala - 发布/订阅中的 Redis 插件阻塞

haskell - 结合仿函数和单子(monad)

haskell - Haskell 中的多行是什么?一个操作符,一个函数,还是别的什么?

php - 使用redis的新闻提要

redis - 如何在 Rust 中使用 Redis 存储/获取结构?

具有时间范围的 Mongodb 交集