假设我有一个基于Scotty的http服务器
SELECT table1_studentname, table2_studentname, etc
( CASE WHEN :variable IN
(SELECT student_id from Table 2)
THEN
......
ELSE
...
END) as table3_studentname
然后我有一个要保持状态scottyServer :: IO ()
scottyServer = do
print ("Starting Server at port " ++ show port)
scotty port routes
routes :: ScottyM()
routes = do get "/service" responseService
get "/users" responseUsers
CircuitBreakerType
使用Haskell如何在Scootty的请求/响应之间保持CircuitBreakerType的状态
我做过的所有状态机示例都是通过IO monad相互传递状态,但是对于Http服务器,我不知道如何保持状态。希望与数据库持久性无关,因为性能会降低。
致谢
答案 0 :(得分:3)
在这种局部应用程序中,您是您的朋友。在C语言中可能使用有罪的全局变量的地方,您可以改为在父(主)例程中显式声明您的值(引用),然后将其通过部分应用程序传递给Web路由处理程序。
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Control.Monad.IO.Class
import Data.IORef
port = 8080
scottyServer :: IO ()
scottyServer = do
print ("Starting Server at port " ++ show port)
ref <- newState initialState
scotty port (routes ref)
routes :: MyStateRef -> ScottyM()
routes ref = get "/users" (responseUsers ref)
responseUsers :: MyStateRef -> ActionM ()
responseUsers ref = do x <- statefulStuff ref
json (show x)
--------------------------------------------------------------------------------
-- Stateful things
initialState :: Int
initialState = 0
type MyState = Int
type MyStateRef = IORef Int -- Could be TVar, MVar, DB address, etc
newState :: MonadIO m => MyState -> m MyStateRef
newState = liftIO . newIORef
statefulStuff :: MonadIO m => MyStateRef -> m MyState
statefulStuff ref =
do x <- liftIO (readIORef ref)
-- N.B. lack of atomicity - that isn't the point of this answer
let y = x + 1
y `seq` liftIO (writeIORef ref y)
pure y