2014-08-27 27 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