2012-03-27 37 views
1

我想了解如何使用warp來編寫web服務,該warp具有我想從所有請求中訪問的長期資源(即,我希望資源存在於服務器的生命週期中,而不是每個請求)。我假設這是ResourceT的用途,但我不確定我是如何做到這一點的。使用長壽命資源(文件句柄)的warp web服務

我特別使用的是我想公開一個文件句柄,我目前已經包含在狀態monad中。如果在使用warp和ResourceT時沒有意義,我很樂意改變這種方法。這段代碼的一個早期版本上可以看到代碼審查:提前https://codereview.stackexchange.com/questions/9177/my-simple-haskell-key-value-file-store

感謝,

馬特

回答

4

最明顯的方法是通過在文件處理中作爲參數傳遞給應用程序。

import Control.Monad.Trans (liftIO) 
import Data.ByteString.Lazy as Bl 
import Network.HTTP.Types 
import Network.Wai 
import Network.Wai.Handler.Warp as Warp 
import System.IO 

doSomethingWithAFileHandle :: Handle -> IO() 
doSomethingWithAFileHandle = 
    undefined -- insert your logic here 

app :: Handle -> Application 
app h req = do 
    let headers = [] 
     body = Bl.empty 

    liftIO $ doSomethingWithAFileHandle h 

    return $! responseLBS ok200 headers body 

main :: IO() 
main = 
    -- get some file handle 
    withBinaryFile "/dev/random" ReadMode $ \ h -> 

    -- and then partially apply it to get an Application 
    Warp.run 3000 (app h) 
+0

這真的很有幫助,謝謝。什麼是正確的擴展方式,以便對文件句柄的訪問進行封裝。我正在考慮類似於我在http://codereview.stackexchange.com/questions/9177/my-simple-haskell-key-value-file-store上使用狀態monad的內容?再次感謝。 – thatismatt 2012-03-27 09:23:52

+1

@thatismatt如果你看看'run'的類型簽名,你會發現它確實需要一個'Request - > ResourceT IO Response'。這並不能讓您靈活地用'ReaderT Handle IO'或StateT等價物取代IO。把它擴展到ReaderT是可以安全的(參見forkable-monad和monad-fork包),但我沒有看到這麼做的好處 – 2012-03-27 16:48:01