2014-08-27 3 views
9

Рассмотрим простейший Скотти приложение:Простые вопросы о Скотти веб рамках Haskell

{-# 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). Но это ничего не показывает. Он не выводит входящие веб-запросы. Как я могу заставить это сделать это? Это было бы полезно для целей ведения журнала.

ответ

11

Предполагая, что вы используете GHC, каждый запрос к серверу scotty по существу создает «зеленый поток», который запланирован во время выполнения GHC. Вы можете легко иметь тысячи тех, кто работает за один раз.

Сам Скотти не регистрирует запросы, но поскольку он построен поверх 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

Спасибо, это работает. Если вы знаете, как ответить на мой следующий вопрос о scotty app за nginx, не стесняйтесь: https://stackoverflow.com/questions/25537495/logging-when-scotty-haskell-web-app-is-running-behind-nginx – stackoverflowuser

+0

Что управляет этими зелеными нитками? что решает, когда и сколько творить и убивать? –

9

1. Что на самом деле происходит, когда люди посещают сайт? Это только один ./app, который работает. Создает ли новый поток в этом же приложении каждый раз, когда каждый пользователь запускает строку «/: word» $ do? Сколько таких потоков может существовать? Тысяча? Десять тысяч?

Скотти строится вокруг warp, но можно использовать любую другую библиотеку, который реализует web application interface (WAI). Новая легкая нить создается с помощью forkIOUnmasked (скрыта в fork в модуле Network.Wai.Handler.Warp.Run). Вы можете иметь много тех:

Параллелизм «легкий», что означает, что и создание потоков и переключение контекста накладные расходы чрезвычайно низки. Планирование потоков Haskell выполняется внутри системы времени исполнения Haskell и не использует никаких пакетов потоков, поставляемых с операционной системой. (source)

Вот performance comparison between nginx and warp, в котором также содержится информация об общей идее основы.

2. После запуска. /app отображается сообщение Установка фазеров для оглушения ... (порт 3000) (ctrl-c для выхода). Но это ничего не показывает. Он не выводит входящие веб-запросы. Как я могу заставить это сделать это? Это было бы полезно для целей ведения журнала.

Какой тип блока do? Он должен быть ScottyM, начиная с scotty :: Port -> ScottyM() -> IO(). Если ScottyM является экземпляром MonadIO, вы можете использовать liftIO вместе с putStrLn (или любым другим действием 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>"] 

Однако, имейте в виду, что вход в терминал не может быть хорошей идеей, когда вы действительно ожидают десять тысяч запросов в секунду.

+0

Спасибо, хорошая информация – stackoverflowuser

Смежные вопросы