考虑一下最简单的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一起运行它。很简单。
./app在运行。当每个用户触发一个get "/:word" $ do行时,是否在同一应用程序中创建了一个新线程?有多少这样的线程可以存在?千人?一万?./app后,它将显示消息Setting phasers to stun... (port 3000) (ctrl-c to quit)。但它没有显示更多的东西。它不输出传入的web请求。我怎么能让它这么做?这对于日志记录非常有用。发布于 2014-08-27 17:23:15
假设您正在使用GHC,每个对scotty服务器的请求实际上都会创建一个由GHC运行时调度的“绿色线程”。你可以很容易地让成千上万的人一次跑步。
Scotty本身不执行任何请求日志记录,但是由于它是构建在围之上的,所以您可以使用它存在的任何中间件组件,例如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>"]发布于 2014-08-27 16:25:21
Scotty是围绕经纱构建的,但可以使用实现web应用程序接口(WAI)的任何其他库。使用forkIOUnmasked (隐藏在模块Network.Wai.Handler.Warp.Run中的fork中)创建一个新的轻量级线程。你可以拥有很多这样的东西:
并发性是“轻量级”的,这意味着线程创建和上下文切换开销都非常低。Haskell线程的调度是在Haskell运行时系统内部完成的,不使用任何操作系统提供的线程包。(来源)
这里有一个nginx与经纱的性能比较,它还包括有关翘曲背后的一般想法的信息。
你的do块是什么类型的?应该是ScottyM,因为scotty :: Port -> ScottyM () -> IO ()。如果ScottyM是MonadIO的一个实例,则可以将liftIO与putStrLn (或任何其他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>"]但是,请记住,当您真的期望每秒一万次请求时,登录到终端可能不是一个好主意。
https://stackoverflow.com/questions/25531574
复制相似问题