{-# options_haddock prune #-}
module Polysemy.Conc.Interpreter.Monitor where
import qualified Control.Exception as Base
import Polysemy.Scoped (interpretScopedH, runScopedAs)
import qualified Polysemy.Time as Time
import Polysemy.Time (Time)
import Polysemy.Conc.Async (withAsync_)
import Polysemy.Conc.Effect.Monitor (
Monitor (Monitor),
MonitorCheck (MonitorCheck),
RestartingMonitor,
ScopedMonitor,
hoistMonitorCheck,
)
import qualified Polysemy.Conc.Effect.Race as Race
import Polysemy.Conc.Effect.Race (Race)
newtype CancelResource =
CancelResource { CancelResource -> MVar ()
signal :: MVar () }
data MonitorCancel =
MonitorCancel
deriving stock (MonitorCancel -> MonitorCancel -> Bool
(MonitorCancel -> MonitorCancel -> Bool)
-> (MonitorCancel -> MonitorCancel -> Bool) -> Eq MonitorCancel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MonitorCancel -> MonitorCancel -> Bool
$c/= :: MonitorCancel -> MonitorCancel -> Bool
== :: MonitorCancel -> MonitorCancel -> Bool
$c== :: MonitorCancel -> MonitorCancel -> Bool
Eq, Int -> MonitorCancel -> ShowS
[MonitorCancel] -> ShowS
MonitorCancel -> String
(Int -> MonitorCancel -> ShowS)
-> (MonitorCancel -> String)
-> ([MonitorCancel] -> ShowS)
-> Show MonitorCancel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MonitorCancel] -> ShowS
$cshowList :: [MonitorCancel] -> ShowS
show :: MonitorCancel -> String
$cshow :: MonitorCancel -> String
showsPrec :: Int -> MonitorCancel -> ShowS
$cshowsPrec :: Int -> MonitorCancel -> ShowS
Show)
deriving anyclass (Show MonitorCancel
Typeable MonitorCancel
Typeable MonitorCancel
-> Show MonitorCancel
-> (MonitorCancel -> SomeException)
-> (SomeException -> Maybe MonitorCancel)
-> (MonitorCancel -> String)
-> Exception MonitorCancel
SomeException -> Maybe MonitorCancel
MonitorCancel -> String
MonitorCancel -> SomeException
forall e.
Typeable e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: MonitorCancel -> String
$cdisplayException :: MonitorCancel -> String
fromException :: SomeException -> Maybe MonitorCancel
$cfromException :: SomeException -> Maybe MonitorCancel
toException :: MonitorCancel -> SomeException
$ctoException :: MonitorCancel -> SomeException
Exception)
monitorRestart ::
∀ t d r a .
Members [Time t d, Resource, Async, Race, Final IO] r =>
MonitorCheck r ->
(CancelResource -> Sem r a) ->
Sem r a
monitorRestart :: forall t d (r :: EffectRow) a.
Members '[Time t d, Resource, Async, Race, Final IO] r =>
MonitorCheck r -> (CancelResource -> Sem r a) -> Sem r a
monitorRestart (MonitorCheck NanoSeconds
interval MVar () -> Sem r ()
check) CancelResource -> Sem r a
use = do
MVar ()
sig <- forall (m :: * -> *) (r :: EffectRow) a.
(Member (Final m) r, Functor m) =>
m a -> Sem r a
embedFinal @IO IO (MVar ())
forall a. IO (MVar a)
newEmptyMVar
Sem r () -> Sem r a -> Sem r a
forall (r :: EffectRow) b a.
Members '[Resource, Race, Async] r =>
Sem r b -> Sem r a -> Sem r a
withAsync_ (forall t d u (r :: EffectRow).
(Member (Time t d) r, TimeUnit u) =>
u -> Sem r () -> Sem r ()
Time.loop_ @t @d NanoSeconds
interval (MVar () -> Sem r ()
check MVar ()
sig)) (MVar () -> Sem r a
spin MVar ()
sig)
where
spin :: MVar () -> Sem r a
spin MVar ()
sig = do
let res :: CancelResource
res = (MVar () -> CancelResource
CancelResource MVar ()
sig)
Sem r (Maybe ()) -> Sem r ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall (m :: * -> *) (r :: EffectRow) a.
(Member (Final m) r, Functor m) =>
m a -> Sem r a
embedFinal @IO (MVar () -> IO (Maybe ())
forall a. MVar a -> IO (Maybe a)
tryTakeMVar MVar ()
sig))
(MonitorCancel -> Sem r a)
-> (a -> Sem r a) -> Either MonitorCancel a -> Sem r a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Sem r a -> MonitorCancel -> Sem r a
forall a b. a -> b -> a
const (MVar () -> Sem r a
spin MVar ()
sig)) a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either MonitorCancel a -> Sem r a)
-> Sem r (Either MonitorCancel a) -> Sem r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall e (r :: EffectRow) a.
Member (Final IO) r =>
Sem (Error e : r) a -> Sem r (Either e a)
errorToIOFinal @MonitorCancel (forall e (r :: EffectRow) a.
(Exception e, Member (Error e) r, Member (Final IO) r) =>
Sem r a -> Sem r a
fromExceptionSem @MonitorCancel (Sem r a -> Sem (Error MonitorCancel : r) a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem r a -> Sem (e : r) a
raise (CancelResource -> Sem r a
use CancelResource
res)))
interpretMonitorRestart ::
∀ t d r .
Members [Time t d, Resource, Async, Race, Final IO] r =>
MonitorCheck r ->
InterpreterFor RestartingMonitor r
interpretMonitorRestart :: forall t d (r :: EffectRow).
Members '[Time t d, Resource, Async, Race, Final IO] r =>
MonitorCheck r -> InterpreterFor RestartingMonitor r
interpretMonitorRestart MonitorCheck r
check =
(forall (q :: (* -> *) -> * -> *) x.
()
-> (CancelResource -> Sem (Opaque q : r) x)
-> Sem (Opaque q : r) x)
-> (forall (q :: (* -> *) -> * -> *) (r0 :: EffectRow) x.
CancelResource
-> Monitor Restart (Sem r0) x
-> Tactical (Monitor Restart) (Sem r0) (Opaque q : r) x)
-> InterpreterFor RestartingMonitor r
forall resource param (effect :: (* -> *) -> * -> *)
(r :: EffectRow).
(forall (q :: (* -> *) -> * -> *) x.
param
-> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> (forall (q :: (* -> *) -> * -> *) (r0 :: EffectRow) x.
resource
-> effect (Sem r0) x -> Tactical effect (Sem r0) (Opaque q : r) x)
-> InterpreterFor (Scoped param effect) r
interpretScopedH (((CancelResource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x)
-> ()
-> (CancelResource -> Sem (Opaque q : r) x)
-> Sem (Opaque q : r) x
forall a b. a -> b -> a
const (forall t d (r :: EffectRow) a.
Members '[Time t d, Resource, Async, Race, Final IO] r =>
MonitorCheck r -> (CancelResource -> Sem r a) -> Sem r a
monitorRestart @t @d ((forall x. Sem r x -> Sem (Opaque q : r) x)
-> MonitorCheck r -> MonitorCheck (Opaque q : r)
forall (r :: EffectRow) (r' :: EffectRow).
(forall x. Sem r x -> Sem r' x)
-> MonitorCheck r -> MonitorCheck r'
hoistMonitorCheck forall x. Sem r x -> Sem (Opaque q : r) x
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem r a -> Sem (e : r) a
raise MonitorCheck r
check))) \ CancelResource {MVar ()
signal :: MVar ()
$sel:signal:CancelResource :: CancelResource -> MVar ()
..} -> \case
Monitor Sem r0 x
ma ->
(()
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x))
-> (f x
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x))
-> Either () (f x)
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Sem (WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
-> ()
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
forall a b. a -> b -> a
const (MonitorCancel
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
forall a e. Exception e => e -> a
Base.throw MonitorCancel
MonitorCancel)) f x
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either () (f x)
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x))
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r))
(Either () (f x))
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Sem (WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) ()
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r)) (f x)
-> Sem
(WithTactics (Monitor Restart) f (Sem r0) (Opaque q : r))
(Either () (f x))
forall a b (r :: EffectRow).
Member Race r =>
Sem r a -> Sem r b -> Sem r (Either a b)
Race.race (forall (m :: * -> *) (r :: EffectRow) a.
(Member (Final m) r, Functor m) =>
m a -> Sem r a
embedFinal @IO (MVar () -> IO ()
forall a. MVar a -> IO a
readMVar MVar ()
signal)) (Sem r0 x -> Tactical (Monitor Restart) (Sem r0) (Opaque q : r) x
forall (m :: * -> *) a (e :: (* -> *) -> * -> *) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem r0 x
ma)
interpretMonitorPure' :: () -> InterpreterFor (Monitor action) r
interpretMonitorPure' :: forall action (r :: EffectRow).
() -> InterpreterFor (Monitor action) r
interpretMonitorPure' ()
_ =
(forall (rInitial :: EffectRow) x.
Monitor action (Sem rInitial) x
-> Tactical (Monitor action) (Sem rInitial) r x)
-> Sem (Monitor action : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
(forall (rInitial :: EffectRow) x.
e (Sem rInitial) x -> Tactical e (Sem rInitial) r x)
-> Sem (e : r) a -> Sem r a
interpretH \case
Monitor Sem rInitial x
ma ->
Sem rInitial x -> Tactical (Monitor action) (Sem rInitial) r x
forall (m :: * -> *) a (e :: (* -> *) -> * -> *) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem rInitial x
ma
interpretMonitorPure :: InterpreterFor (ScopedMonitor action) r
interpretMonitorPure :: forall action (r :: EffectRow).
InterpreterFor (ScopedMonitor action) r
interpretMonitorPure =
(() -> Sem r ())
-> (forall (q :: (* -> *) -> * -> *).
() -> InterpreterFor (Monitor action) (Opaque q : r))
-> InterpreterFor (Scoped () (Monitor action)) r
forall resource param (effect :: (* -> *) -> * -> *)
(r :: EffectRow).
(param -> Sem r resource)
-> (forall (q :: (* -> *) -> * -> *).
resource -> InterpreterFor effect (Opaque q : r))
-> InterpreterFor (Scoped param effect) r
runScopedAs (Sem r () -> () -> Sem r ()
forall a b. a -> b -> a
const Sem r ()
forall (f :: * -> *). Applicative f => f ()
unit) forall action (r :: EffectRow).
() -> InterpreterFor (Monitor action) r
forall (q :: (* -> *) -> * -> *).
() -> InterpreterFor (Monitor action) (Opaque q : r)
interpretMonitorPure'