2014-08-27 53 views
9

簡單的問題考慮最簡單的斯科蒂應用:關於斯科蒂Haskell的Web框架

{-# LANGUAGE OverloadedStrings #-} 
import Web.Scotty 

import Data.Monoid (mconcat) 

main = scotty 3000 $ do 
    get "/:word" $ do 
     beam <- param "word" 
     html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"] 

我把這個代碼放到app.hs並與GHC編譯。我用./app運行它。簡單。

  1. 當人們訪問該網站時真的發生了什麼?這只是一個./app正在運行。每當用戶觸發get "/:word" $ do行時,是否會在此應用程序中創建新線程?有多少這樣的線程可以存在?千?萬?

  2. 運行後./app顯示消息Setting phasers to stun... (port 3000) (ctrl-c to quit)。但它沒有顯示任何更多。它不輸出傳入的Web請求。我怎樣才能做到這一點?這對於日誌記錄很有用。

回答

11

假設您正在使用GHC,scotty服務器的每個請求基本上都會創建一個由GHC運行時計劃的「綠色線程」。您可以輕鬆地擁有數千個同時運行的應用程序。

Scotty本身不會做任何請求日誌記錄,但由於它建立在WAI之上,所以您可以使用任何存在的中間件組件,例如RequestLogger

{-# LANGUAGE OverloadedStrings #-} 
import Web.Scotty 
import Network.Wai.Middleware.RequestLogger 

import Data.Monoid (mconcat) 

main = scotty 3000 $ do 
    middleware logStdoutDev 

    get "/:word" $ do 
     beam <- param "word" 
     html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"] 
+0

謝謝,這個工程。如果你知道如何回答我關於nginx背後的一個scotty應用程序的下一個問題,請感受一下:https://stackoverflow.com/questions/25537495/logging-when-scotty-haskell-web-app-is-running-behind-nginx – stackoverflowuser 2014-08-27 21:48:26

+0

什麼管理這些綠色線程?什麼決定什麼時候和多少人創造和殺死? – 2016-04-22 16:13:44

9

1.真的會發生什麼,當人們訪問網站?它只有一個./app正在運行。每當用戶觸發get「/:word」$ do行時,是否會在此應用程序中創建新線程?有多少這樣的線程可以存在?千?萬?

Scotty構建在warp左右,但可以使用任何其他實現web application interface (WAI)的庫。使用forkIOUnmasked(隱藏在模塊Network.Wai.Handler.Warp.Run中的fork中)創建了一個新的輕量級線程。你可以有那些許多

併發是「輕量級」,這意味着這兩個線程的創建和上下文切換的開銷非常低。 Haskell線程的調度在Haskell運行時系統內部完成,並且不使用任何操作系統提供的線程包。 (source)

這是performance comparison between nginx and warp,其中還包括關於warp背後的一般思想的信息。

2.運行./app後,顯示消息設置階段器眩暈...(端口3000)(ctrl-c退出)。但它沒有顯示任何更多。它不輸出傳入的Web請求。我怎樣才能做到這一點?這對於日誌記錄很有用。

你的do塊的類型是什麼?它應該是ScottyM,因爲scotty :: Port -> ScottyM() -> IO()。如果ScottyMMonadIO的實例,則可以使用liftIOputStrLn(或任何其他IO操作)。

現在,ScottyM實際上是ScottyT的一個同義詞,它實際上是MonadIO的一個實例。另外,內部單子ActionM也是ActionT的同義類型,其也是MonadIO。因此,日誌記錄是那麼容易,因爲

main = scotty 3000 $ do 
    liftIO $ putStrLn "incoming request" 
    get "/:word" $ do 
     beam <- param "word" 
     liftIO $ print $ mconcat ["get, word = ", beam] 
     html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"] 

但是,請記住,登錄到終端可能不是一個好主意,當你真的希望每秒10000個請求。

+0

謝謝,很好的信息 – stackoverflowuser 2014-08-27 21:49:28