servidor programar equipos encendido desde automatico apagar apagado active haskell yesod

haskell - programar - ¿Cómo implemento un comando de apagado en un servidor WAI?



programar encendido y apagado ubuntu (1)

  1. Utilice un MVar. Bloquee el hilo principal hasta que la MVar haya sido señalizada, luego limpie y salga.
  2. Llamar a la exitImmediately . Una de las maneras más rápidas de demorar el proceso, y también terriblemente molesta de depurar. No creo que los finalizadores / paréntesis / finalmente los bloques se llamen en el camino hacia abajo, dependiendo de su aplicación, puede dañar el estado.
  3. Lanzar una excepción al hilo principal. Warp.run no Warp.run excepciones, por lo que esto funciona al permitir que el controlador de excepciones predeterminado en el subproceso principal (y solo el subproceso principal) finalice el proceso.

Como han mencionado otros, usar una MVar es probablemente la mejor opción. Incluí a los otros por el bien de la integridad, pero tienen su lugar. throwTo se usa de alguna manera en la biblioteca base y he trabajado en algunas aplicaciones que usan el equivalente en C de exitImmediately : exit() , aunque no he encontrado ninguna aplicación de Haskell que use este método.

{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} module Main (main) where import Control.Concurrent (MVar, ThreadId, forkIO, myThreadId, newEmptyMVar, putMVar, takeMVar) import Control.Exception (Exception, throwTo) import Control.Monad.Trans (liftIO) import Data.ByteString (ByteString) import Data.Data (Data, Typeable) import Data.Enumerator (Iteratee) import Network.HTTP.Types import Network.Wai as Wai import Network.Wai.Handler.Warp as Warp import System.Exit (ExitCode (ExitSuccess)) import System.Posix.Process (exitImmediately) data Shutdown = Shutdown deriving (Data, Typeable, Show) instance Exception Shutdown app :: ThreadId -> MVar () -> Request -> Iteratee ByteString IO Response app mainThread shutdownMVar Request{pathInfo = pathInfo} = do liftIO $ case pathInfo of ["shutdownByThrowing"] -> throwTo mainThread Shutdown ["shutdownByMVar"] -> putMVar shutdownMVar () ["shutdownByExit"] -> exitImmediately ExitSuccess _ -> return () return $ responseLBS statusOK [headerContentType "text/plain"] "ok" main :: IO () main = do mainThread <- myThreadId shutdownMVar <- newEmptyMVar forkIO $ Warp.run 3000 (app mainThread shutdownMVar) takeMVar shutdownMVar

Me gustaría implementar un comando de ''cierre elegante'' para mi aplicación web (en oposición a mi primer instinto, que es simplemente pedirle a la gente que mate el proceso)

Mis dos primeros intentos consistieron en

  1. liftIO exitSuccess
  2. E.yield (responseLBS statusOK [G.contentType "text/plain"] "") E.EOF

Ambos de los cuales simplemente devolvieron alegremente un resultado al cliente y continuaron escuchando. ¿Hay algo que una aplicación pueda hacer para matar el servidor? ¿Es esto incluso algo razonable para querer hacer?

Confieso que no tengo una comprensión muy sólida de iteración, solo lo suficiente para saber que puedo consumir mi entrada y que Iteratee es una instancia de MonadIO.