我有一个相对简单的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)
由于
答案 0 :(得分:2)
非常感谢Freenode上Kaini
的{{1}}:
#haskell
使用main
进行愚蠢的尝试,无限期地阻止主线程。这当然意味着永远产生Redis和stdout线程,因此达到文件开放限制。
将forever
重写为
main
工作得更好!