HTTPクライアントが接続を切断したとき(または他の現実の世界が発生したとき)にクリーンアップを実行する方法を理解できません。にラップしようとしましSource
たaddCleanup
が、呼び出されません。
これが、無限のソースストリーミングバイトストリングの私の最小限の例です。
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
import Data.ByteString.Lazy.Char8 ()
import Control.Monad
import Control.Monad.Trans
import Control.Concurrent (threadDelay)
import Data.Conduit
import Blaze.ByteString.Builder (Builder)
import qualified Blaze.ByteString.Builder.ByteString as BBBB
import qualified Data.ByteString.Char8 as BS
stream :: Source (ResourceT IO) (Flush Builder)
stream = addCleanup (\_ -> liftIO $ putStrLn "cleanup.") $ do
liftIO $ putStrLn "source started."
yield Flush
forever $ do
yield $ bchunk "whatever"
yield Flush
liftIO $ threadDelay 10000
app :: Application
app req = do
liftIO $ putStrLn "in the handler."
return $ ResponseSource status200 [("Content-Type", "text/plain")] stream
main :: IO ()
main = run 3000 app
bchunk = Chunk . BBBB.fromByteString . BS.pack
httpリクエストでヒットすると、「起動」通知が表示され、stream
データのパージが開始されます。ただし、接続を閉じた後、「クリーンアップ」は行われません。メッセージが表示され、アクションは実行されないため、実際のコードでリソースがリークします。