Haskell守护程序无法从“getAddrInfo”/“太多打开文件”错误中删除Redis

时间:2013-09-12 13:18:35

标签: haskell redis daemon

我有一个相对简单的Haskell守护进程blpop来自Redis的东西,并将它们写入一个线程中的一个通道,并从通道中读取它们并将它们打印到另一个中的stdout。

在运行它时,它开始很好,然后一段时间后,我在stderr上得到以下内容:

hogstash: getAddrInfo: does not exist (nodename nor servname provided, or not known)

并在我的system.log(OSX)中查看以下内容:

hogstash[11281]: dnssd_clientstub deliver_request: socketpair failed 24 (Too many open files)

我从中推断出,我正在做一些无限线程的DNS查找,但我不明白怎么做,而且我对Haskell的熟悉程度不足以真正得到如何调试它。

主程序如下:

import Hogstash.Inputs.Redis
import Hogstash.Event
import Hogstash.Outputs.Stdout

import Control.Concurrent
import Control.Concurrent.BoundedChan
import Control.Monad

main = forever $ do
           channel <- newBoundedChan 10
           forkIO $ do
               connection <- tmpHaxx
               forever $ getEvent connection "logstash:beaver" channel
           forkIO $ forever $ stdout channel

stdout只是:

module Hogstash.Outputs.Stdout where

import Control.Concurrent.BoundedChan as BC
import Hogstash.Event

stdout :: BoundedChan Event -> IO ()
stdout channel = do 
                     event <- readChan channel
                     putStrLn $ show event

getEvent是:

module Hogstash.Inputs.Redis where

import Database.Redis

import Hogstash.Event

import Control.Concurrent
import Control.Concurrent.BoundedChan as BC
import qualified Data.ByteString.Char8 as BSC


eventFromByteString :: BSC.ByteString -> Event
eventFromByteString _ = Event

listListen key = blpop [key] 0

tmpHaxx = connect defaultConnectInfo -- FIXME Remove this

getEvent :: Connection -> String -> BoundedChan Event -> IO ()

getEvent a b = getEvent' a (BSC.pack b)

getEvent' ci key channel = do
                                fnar <- pullEvent ci key
                                case fnar of
                                    Just e -> BC.writeChan channel e
                                    Nothing -> return ()

pullEvent :: Connection -> BSC.ByteString -> IO (Maybe Event)
pullEvent connection key = do
                                    event_data <- runRedis connection $ listListen key
                                    return (case event_data of
                                        Left a -> Nothing
                                        Right a -> extractEvent a)

extractEvent :: Maybe (a, BSC.ByteString) -> Maybe Event
extractEvent = fmap (eventFromByteString . snd)

由于

1 个答案:

答案 0 :(得分:2)

非常感谢Freenode上Kaini的{​​{1}}:

#haskell使用main进行愚蠢的尝试,无限期地阻止主线程。这当然意味着永远产生Redis和stdout线程,因此达到文件开放限制。

forever重写为

main

工作得更好!