用 20 行 Haskell 寫 FaaS 服務器

FaaS 是 Function as a Service 的簡稱,是構建 Serverless 的一種框架。
那么 FaaS 做了什么事情呢?簡單來講 FaaS 將 HTTP 請求轉發(fā)到可執(zhí)行命令,然后將命令的執(zhí)行結果轉發(fā)給 HTTP Response。

有了這么一條業(yè)務邏輯我們就可以構建自己的 FaaS 服務器。

首先定義可執(zhí)行命令的數(shù)據(jù)結構:

data Proc = Proc { procFuncName :: String
                 , procName :: String
                 , procArgv :: [String]
                 }
  • procFuncName 為 HTTP 請求的函數(shù)名字
  • procName 為可執(zhí)行的命令
  • procArgv 為可執(zhí)行命令的參數(shù)

執(zhí)行命令使用 System.Process.ByteString.Lazy 里面的 readProcessWithExitCode

runProc :: Proc -> ByteString -> IO (Either ByteString ByteString)
runProc (Proc { procName = name, procArgv = argv}) wb = do
  (code, out, err) <- readProcessWithExitCode name argv wb
  case code of 
    ExitSuccess   -> return (Right out)
    ExitFailure _ -> return (Left err)

使用 Web.Scotty 來構建 web 服務器

processHandler :: (String -> Maybe Proc) -> ActionM ()
processHandler getProc = do 
  func <- param "func"
  case (getProc func) of
    Nothing -> do 
        status status404
        raw LB.empty
    Just proc -> do 
        wb <- body
        result <- liftIO $ runProc proc wb
        case result of 
          Left err -> do 
            status status500
            raw err
          Right out -> raw out

catProc :: Proc 
catProc = Proc { procFuncName = "cat"
               , procName     = "cat"
               , procArgv     = []
               }

getProcByFuncName :: String -> Maybe Proc
getProcByFuncName "cat" = Just catProc
getProcByFuncName _     = Nothing

main = scotty 3000 $ do
    post "/function/:func" $ processHandler getProcByFuncName

到這里 FaaS 服務器已經(jīng)完成。

FaaS 服務器就這么簡單,在生產環(huán)境上我們還需要做一些事情,比如 函數(shù)可以配置。

完整的代碼參見 func

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容