关于scotty Haskell Web框架的简单问题

时间:2014-08-27 15:46:43

标签: haskell scotty haskell-warp haskell-wai

考虑最简单的scotty应用程序:

{-# 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请求。我该怎么做呢?这对于日志记录非常有用。

2 个答案:

答案 0 :(得分: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>"]

答案 1 :(得分:9)

  

1。当人们访问该网站时会发生什么?它只有一个./app正在运行。每当每个用户触发get&#34; /:word&#34;时,是否会在同一个应用中创建新线程。 $ do line?有多少这样的线程可以存在?千?一万?

Scotty是围绕warp构建的,但可以使用任何其他实现web application interface (WAI)的库。使用forkIOUnmasked创建一个新的轻量级线程(隐藏在模块Network.Wai.Handler.Warp.Run中的fork中)。您可以许多

  

并发是&#34;轻量级&#34;,这意味着线程创建和上下文切换开销都非常低。 Haskell线程的调度是在Haskell运行时系统内部完成的,并没有使用任何操作系统提供的线程包。 (source)

这里是performance comparison between nginx and warp,其中还包含有关扭曲背后的一般概念的信息。

  

2。运行./app后,它显示消息设置阶段到stun ...(端口3000)(ctrl-c退出)。但它没有显示更多。它不会输出传入的Web请求。我该怎么做呢?这对于日志记录非常有用。

do区块的类型是什么?它应该是ScottyM,因为scotty :: Port -> ScottyM () -> IO ()。如果ScottyMMonadIO的实例,则可以将liftIOputStrLn(或任何其他IO操作一起使用)。

现在,ScottyM实际上是ScottyT的类型同义词,实际上是MonadIO的实例。此外,内部monad 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>"]

但是,请记住,当您真的希望每秒有一万个请求时,记录到终端可能不是一个好主意。