Tôi đã viết thư viện có tên amqp-worker cung cấp chức năng gọi là worker
để thăm dò hàng đợi tin nhắn (như RabbitMQ) cho tin nhắn, gọi trình xử lý khi tìm thấy tin nhắn. Sau đó, nó quay trở lại để bỏ phiếu.Rò rỉ bộ nhớ trong chức năng IO đệ quy - PAP
Đó là bộ nhớ bị rò rỉ. Tôi đã lược tả nó và biểu đồ cho biết PAP
(ứng dụng chức năng một phần) là thủ phạm. Sự rò rỉ trong mã của tôi ở đâu? Làm cách nào để tránh rò rỉ khi lặp lại trong IO
với forever
?
Dưới đây là một số chức năng có liên quan. The full source is here.
Example Program. Đây rò rỉ
main :: IO()
main = do
-- connect
conn <- Worker.connect (fromURI "amqp://guest:[email protected]:5672")
-- initialize the queues
Worker.initQueue conn queue
Worker.initQueue conn results
-- publish a message
Worker.publish conn queue (TestMessage "hello world")
-- create a worker, the program loops here
Worker.worker def conn queue onError (onMessage conn)
worker :: (FromJSON a, MonadBaseControl IO m, MonadCatch m) => WorkerOptions -> Connection -> Queue key a -> (WorkerException SomeException -> m()) -> (Message a -> m()) -> m()
worker opts conn queue onError action =
forever $ do
eres <- consumeNext (pollDelay opts) conn queue
case eres of
Error (ParseError reason bd) ->
onError (MessageParseError bd reason)
Parsed msg ->
catch
(action msg)
(onError . OtherException (body msg))
liftBase $ threadDelay (loopDelay opts)
consumeNext :: (FromJSON msg, MonadBaseControl IO m) => Microseconds -> Connection -> Queue key msg -> m (ConsumeResult msg)
consumeNext pd conn queue =
poll pd $ consume conn queue
poll :: (MonadBaseControl IO m) => Int -> m (Maybe a) -> m a
poll us action = do
ma <- action
case ma of
Just a -> return a
Nothing -> do
liftBase $ threadDelay us
poll us action
gì phiên bản ghc của bạn và cách bạn biên dịch? – jberryman
Nó được thiết lập để lts-7.3 vì vậy đó là GHC 8.0.1. Tôi đang biên dịch với ngăn xếp cài đặt - hồ sơ. Nhưng tôi bị rò rỉ bộ nhớ với một cài đặt ngăn xếp bình thường. Sử dụng các tùy chọn ghc mặc định từ mẫu ngăn xếp: -treaded -rtsopts -with-rtsopts = -N –
Ví dụ này rất xa tối thiểu - bạn đang nhập toàn bộ thư viện của mình ('Network.AMQP.Worker') trong chương trình ví dụ của bạn. Khi nó đứng, điều này là quá rộng. – user2407038