respawn process on error

This commit is contained in:
Dmitry Zuikov 2023-05-25 13:01:58 +03:00
parent 66ac8cee18
commit 52284f61ab
3 changed files with 47 additions and 12 deletions

View File

@ -60,15 +60,16 @@ import Crypto.Saltine (sodiumInit)
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Lazy qualified as LBS import Data.ByteString.Lazy qualified as LBS
import Data.ByteString qualified as BS import Data.ByteString qualified as BS
import Data.Cache qualified as Cache
import Data.Function import Data.Function
import Data.List qualified as L import Data.List qualified as L
import Data.Map qualified as Map import Data.Map qualified as Map
import Data.Maybe import Data.Maybe
import Data.Set qualified as Set import Data.Set qualified as Set
import Data.Set (Set) import Data.Set (Set)
import Data.Text.Encoding qualified as TE
import Data.Text qualified as Text import Data.Text qualified as Text
import Data.Text (Text) import Data.Text (Text)
import Data.Text.Encoding qualified as TE
import GHC.Stats import GHC.Stats
import GHC.TypeLits import GHC.TypeLits
import Lens.Micro.Platform import Lens.Micro.Platform
@ -79,7 +80,8 @@ import System.Exit
import System.IO import System.IO
import System.Mem import System.Mem
import System.Metrics import System.Metrics
import Data.Cache qualified as Cache import System.Posix.Process
import System.Environment
import UnliftIO.Exception qualified as U import UnliftIO.Exception qualified as U
-- import UnliftIO.STM -- import UnliftIO.STM
@ -167,7 +169,8 @@ makeLenses 'RPCOpt
data RPCCommand = data RPCCommand =
POKE DIE
| POKE
| ANNOUNCE (Hash HbSync) | ANNOUNCE (Hash HbSync)
| PING (PeerAddr L4Proto) (Maybe (Peer L4Proto)) | PING (PeerAddr L4Proto) (Maybe (Peer L4Proto))
| CHECK PeerNonce (PeerAddr L4Proto) (Hash HbSync) | CHECK PeerNonce (PeerAddr L4Proto) (Hash HbSync)
@ -185,6 +188,7 @@ data PeerOpts =
, _listenRpc :: Maybe String , _listenRpc :: Maybe String
, _peerCredFile :: Maybe FilePath , _peerCredFile :: Maybe FilePath
, _peerConfig :: Maybe FilePath , _peerConfig :: Maybe FilePath
, _peerRespawn :: Maybe Bool
} }
deriving stock (Data) deriving stock (Data)
@ -234,6 +238,7 @@ runCLI = join . customExecParser (prefs showHelpOnError) $
parser = hsubparser ( command "init" (info pInit (progDesc "creates default config")) parser = hsubparser ( command "init" (info pInit (progDesc "creates default config"))
<> command "run" (info pRun (progDesc "run peer")) <> command "run" (info pRun (progDesc "run peer"))
<> command "poke" (info pPoke (progDesc "poke peer by rpc")) <> command "poke" (info pPoke (progDesc "poke peer by rpc"))
<> command "die" (info pDie (progDesc "die cmd"))
<> command "announce" (info pAnnounce (progDesc "announce block")) <> command "announce" (info pAnnounce (progDesc "announce block"))
<> command "ping" (info pPing (progDesc "ping another peer")) <> command "ping" (info pPing (progDesc "ping another peer"))
<> command "fetch" (info pFetch (progDesc "fetch block")) <> command "fetch" (info pFetch (progDesc "fetch block"))
@ -262,7 +267,9 @@ runCLI = join . customExecParser (prefs showHelpOnError) $
c <- optional confOpt c <- optional confOpt
pure $ PeerOpts pref l r k c resp <- optional $ flag' True ( long "respawn" <> short 'r' <> help "respawn process")
pure $ PeerOpts pref l r k c resp
pRun = do pRun = do
runPeer <$> common runPeer <$> common
@ -271,6 +278,10 @@ runCLI = join . customExecParser (prefs showHelpOnError) $
RPCOpt <$> optional confOpt RPCOpt <$> optional confOpt
<*> optional rpcOpt <*> optional rpcOpt
pDie = do
rpc <- pRpcCommon
pure $ runRpcCommand rpc DIE
pPoke = do pPoke = do
rpc <- pRpcCommon rpc <- pRpcCommon
pure $ runRpcCommand rpc POKE pure $ runRpcCommand rpc POKE
@ -358,7 +369,7 @@ runCLI = join . customExecParser (prefs showHelpOnError) $
myException :: SomeException -> IO () myException :: SomeException -> IO ()
myException e = err ( show e ) >> notice "RESTARTING..." myException e = err ( show e )
newtype CredentialsM e s m a = newtype CredentialsM e s m a =
@ -417,17 +428,28 @@ instance ( Monad m
response = lift . response response = lift . response
-- runPeer :: forall e . (e ~ UDP, Nonce (RefLogUpdate e) ~ BS.ByteString) => PeerOpts -> IO () respawn :: PeerOpts -> IO ()
respawn opts = case view peerRespawn opts of
Just True -> do
let secs = 5
notice $ "RESPAWNING in" <+> viaShow secs <> "s"
pause @'Seconds secs
self <- getExecutablePath
args <- getArgs
print (self, args)
executeFile self False args Nothing
_ -> exitFailure
runPeer :: forall e s . ( e ~ L4Proto runPeer :: forall e s . ( e ~ L4Proto
, FromStringMaybe (PeerAddr e) , FromStringMaybe (PeerAddr e)
, s ~ Encryption e , s ~ Encryption e
) => PeerOpts -> IO () ) => PeerOpts -> IO ()
runPeer opts = fix \me -> U.handle (\e -> myException e runPeer opts = U.handle (\e -> myException e
>> performGC >> performGC
>> pause @'Seconds 10 >> respawn opts
>> me ) $ runResourceT do
) $ runResourceT do
metrics <- liftIO newStore metrics <- liftIO newStore
@ -867,6 +889,8 @@ runPeer opts = fix \me -> U.handle (\e -> myException e
void $ liftIO $ waitAnyCancel workers void $ liftIO $ waitAnyCancel workers
let dieAction _ = do
liftIO $ die "received die command"
let pokeAction _ = do let pokeAction _ = do
who <- thatPeer (Proxy @(RPC e)) who <- thatPeer (Proxy @(RPC e))
@ -945,6 +969,7 @@ runPeer opts = fix \me -> U.handle (\e -> myException e
request who (RPCRefLogGetAnswer @e h) request who (RPCRefLogGetAnswer @e h)
let arpc = RpcAdapter pokeAction let arpc = RpcAdapter pokeAction
dieAction
dontHandle dontHandle
dontHandle dontHandle
annAction annAction
@ -1035,6 +1060,7 @@ withRPC o cmd = rpcClientMain o $ runResourceT do
let adapter = let adapter =
RpcAdapter dontHandle RpcAdapter dontHandle
dontHandle
(liftIO . atomically . writeTQueue pokeQ) (liftIO . atomically . writeTQueue pokeQ)
(liftIO . atomically . writeTQueue pokeFQ) (liftIO . atomically . writeTQueue pokeFQ)
(const $ liftIO exitSuccess) (const $ liftIO exitSuccess)
@ -1074,6 +1100,10 @@ withRPC o cmd = rpcClientMain o $ runResourceT do
exitSuccess exitSuccess
RPCDie{} -> do
pause @'Seconds 0.25
liftIO exitSuccess
RPCPoke{} -> do RPCPoke{} -> do
let onTimeout = do pause @'Seconds 1.5 let onTimeout = do pause @'Seconds 1.5
Log.info "no-one-is-here" Log.info "no-one-is-here"
@ -1117,6 +1147,7 @@ withRPC o cmd = rpcClientMain o $ runResourceT do
runRpcCommand :: FromStringMaybe (IPAddrPort L4Proto) => RPCOpt -> RPCCommand -> IO () runRpcCommand :: FromStringMaybe (IPAddrPort L4Proto) => RPCOpt -> RPCCommand -> IO ()
runRpcCommand opt = \case runRpcCommand opt = \case
DIE -> withRPC opt RPCDie
POKE -> withRPC opt RPCPoke POKE -> withRPC opt RPCPoke
PING s _ -> withRPC opt (RPCPing s) PING s _ -> withRPC opt (RPCPing s)
ANNOUNCE h -> withRPC opt (RPCAnnounce h) ANNOUNCE h -> withRPC opt (RPCAnnounce h)

View File

@ -23,7 +23,8 @@ data SetLogging =
instance Serialise SetLogging instance Serialise SetLogging
data RPC e = data RPC e =
RPCPoke RPCDie
| RPCPoke
| RPCPing (PeerAddr e) | RPCPing (PeerAddr e)
| RPCPong (PeerAddr e) | RPCPong (PeerAddr e)
| RPCPokeAnswer (PubKey 'Sign (Encryption e)) | RPCPokeAnswer (PubKey 'Sign (Encryption e))
@ -59,6 +60,7 @@ makeLenses 'RPCEnv
data RpcAdapter e m = data RpcAdapter e m =
RpcAdapter RpcAdapter
{ rpcOnPoke :: RPC e -> m () { rpcOnPoke :: RPC e -> m ()
, rpcOnDie :: RPC e -> m ()
, rpcOnPokeAnswer :: PubKey 'Sign (Encryption e) -> m () , rpcOnPokeAnswer :: PubKey 'Sign (Encryption e) -> m ()
, rpcOnPokeAnswerFull :: Text -> m () , rpcOnPokeAnswerFull :: Text -> m ()
, rpcOnAnnounce :: Hash HbSync -> m () , rpcOnAnnounce :: Hash HbSync -> m ()
@ -112,6 +114,7 @@ rpcHandler :: forall e m . ( MonadIO m
=> RpcAdapter e m -> RPC e -> m () => RpcAdapter e m -> RPC e -> m ()
rpcHandler adapter = \case rpcHandler adapter = \case
p@RPCDie{} -> rpcOnDie adapter p
p@RPCPoke{} -> rpcOnPoke adapter p p@RPCPoke{} -> rpcOnPoke adapter p
(RPCPokeAnswer k) -> rpcOnPokeAnswer adapter k (RPCPokeAnswer k) -> rpcOnPokeAnswer adapter k
(RPCPokeAnswerFull k) -> rpcOnPokeAnswerFull adapter k (RPCPokeAnswerFull k) -> rpcOnPokeAnswerFull adapter k

View File

@ -64,6 +64,7 @@ common common-deps
, http-types , http-types
, wai-extra , wai-extra
, unliftio , unliftio
, unix
common shared-properties common shared-properties
ghc-options: ghc-options: