hbs2/hbs2-tests/test/TestRefChanNotify.hs

157 lines
4.4 KiB
Haskell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE UndecidableInstances #-}
module Main where
import HBS2.Prelude.Plated
import HBS2.Actors.Peer
import HBS2.Base58
import HBS2.OrDie
import HBS2.Hash
import HBS2.Data.Types.Refs
import HBS2.Net.Auth.Credentials
import HBS2.Polling
import HBS2.Misc.PrettyStuff
import HBS2.System.Dir
import HBS2.System.Logger.Simple.ANSI hiding (info)
import HBS2.Net.Messaging.Unix
import HBS2.Net.Proto.Notify
import HBS2.Net.Proto.Service
import HBS2.Peer.Proto.RefChan
import HBS2.Peer.Notify
import HBS2.Peer.RPC.API.Peer
-- import HBS2.Peer.RPC.API.RefLog
-- import HBS2.Peer.RPC.API.LWWRef
-- import HBS2.Peer.RPC.API.Storage
-- import HBS2.Peer.RPC.Client.StorageClient
import HBS2.Peer.CLI.Detect
import HBS2.Peer.Proto.RefLog
import Data.Config.Suckless
import Data.Config.Suckless.Script
import HBS2.System.Logger.Simple.ANSI
import Data.Maybe
import System.Environment
import Control.Monad.Trans.Cont
import Control.Monad.Reader
import Lens.Micro.Platform
data MyEnv =
MyEnv
{ _myRefChan :: Maybe (RefChanId L4Proto)
}
makeLenses ''MyEnv
main :: IO ()
main = do
work
`finally` do
setLoggingOff @DEBUG
setLoggingOff @TRACE
setLoggingOff @NOTICE
setLoggingOff @ERROR
setLoggingOff @WARN
respawned :: MonadUnliftIO m => m a1 -> m a2
respawned action = do
fix \next -> do
try @_ @SomeException action
warn $ red "respawning..."
pause @'Seconds 2
next
work :: IO ()
work = do
setLogging @WARN (toStderr . logPrefix "[warn] ")
setLogging @ERROR (toStderr . logPrefix "[error] ")
setLogging @DEBUG (toStderr . logPrefix "[debug] ")
setLogging @TRACE (toStderr . logPrefix "[trace] ")
setLogging @NOTICE toStdout
tv <- newTVarIO (MyEnv mzero)
let dict = makeDict @C do
entry $ bindMatch "--refchan" $ nil_ \case
[SignPubKeyLike rchan] -> do
atomically $ modifyTVar tv (set myRefChan (Just rchan))
_ -> throwIO $ BadFormException @C nil
argz <- getArgs
forms <- parseTop (unlines $ unwords <$> splitForms argz)
& either (error.show) pure
void $ run dict forms
rchan <- readTVarIO tv <&> view myRefChan
>>= orThrowUser "refchan not set"
notice $ yellow "refchan set" <+> pretty (AsBase58 rchan)
respawned $ flip runContT pure do
-- NOTE: dont-retry
-- MUDontRetry -- ВАЖНО
-- что бы UnixClient не пытался перезапустить транспорт
-- т.к кажется в этом случае некорректно будут работать
-- нотификации ( не будет создан новый сокет, а будут
-- идти в старый. возможно это надо пофиксить, но пока
-- непонятно, как )
--
-- Короче, запретить ему повторный коннект, ловить
-- исключения и выход из клиентов и всё по новой.
--
-- так лучше
--
let o = [MUWatchdog 10]
soname <- detectRPC
>>= orThrowUser "hbs2-peer not found"
client <- liftIO $ race (pause @'Seconds 1) (newMessagingUnixOpts o False 1.0 soname)
>>= orThrowUser ("can't connect to" <+> pretty soname)
notif <- ContT $ withAsync (runMessagingUnix client)
sink <- newNotifySink
p1 <- ContT $ withAsync $ flip runReaderT client $ do
runProto @UNIX
[ makeResponse (makeNotifyClient @(RefChanEvents L4Proto) sink)
]
psink <- ContT $ withAsync $ flip runReaderT client $ do
debug $ red "notify restarted!"
runNotifyWorkerClient sink
-- NOTE: wrap-to-thread-to-kill
-- важно обернуть это в поток, что бы
-- можно было пристрелить, если кто-то еще
-- отгниёт из других потоков
-- иначе будет висеть вечно
psink2 <- ContT $ withAsync do
runNotifySink sink (RefChanNotifyKey rchan) $ \case
RefChanUpdated r v -> do
notice $ red "refchan updated" <+> pretty (AsBase58 r) <+> pretty v
_ -> do
notice $ "some other refchan event happened"
void $ waitAnyCatchCancel [notif,p1,psink,psink2]