module Wire.Sem.Concurrency.Sequential where

import Imports
import Polysemy
import Wire.Sem.Concurrency

------------------------------------------------------------------------------

-- | Safely perform "concurrency" by doing it sequentially.
sequentiallyPerformConcurrency :: Sem (Concurrency safe ': r) a -> Sem r a
sequentiallyPerformConcurrency :: forall (safe :: ConcurrencySafety) (r :: [(* -> *) -> * -> *]) a.
Sem (Concurrency safe : r) a -> Sem r a
sequentiallyPerformConcurrency = (forall (rInitial :: [(* -> *) -> * -> *]) x.
 Concurrency safe (Sem rInitial) x
 -> Tactical (Concurrency safe) (Sem rInitial) r x)
-> Sem (Concurrency safe : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]) a.
(forall (rInitial :: [(* -> *) -> * -> *]) x.
 e (Sem rInitial) x -> Tactical e (Sem rInitial) r x)
-> Sem (e : r) a -> Sem r a
interpretH ((forall (rInitial :: [(* -> *) -> * -> *]) x.
  Concurrency safe (Sem rInitial) x
  -> Tactical (Concurrency safe) (Sem rInitial) r x)
 -> Sem (Concurrency safe : r) a -> Sem r a)
-> (forall (rInitial :: [(* -> *) -> * -> *]) x.
    Concurrency safe (Sem rInitial) x
    -> Tactical (Concurrency safe) (Sem rInitial) r x)
-> Sem (Concurrency safe : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ \case
  UnsafePooledMapConcurrentlyN Int
_ a1 -> Sem rInitial b
f t a1
t -> do
    f ()
st <- Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f ())
forall (f :: * -> *) (m :: * -> *) (r :: [(* -> *) -> * -> *])
       (e :: (* -> *) -> * -> *).
Sem (WithTactics e f m r) (f ())
getInitialStateT
    f [a1] -> Sem (Concurrency safe : r) (f [b])
ftraverse <- ([a1] -> Sem rInitial [b])
-> Sem
     (WithTactics (Concurrency safe) f (Sem rInitial) r)
     (f [a1] -> Sem (Concurrency safe : r) (f [b]))
forall a (m :: * -> *) b (e :: (* -> *) -> * -> *) (f :: * -> *)
       (r :: [(* -> *) -> * -> *]).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT (([a1] -> Sem rInitial [b])
 -> Sem
      (WithTactics (Concurrency safe) f (Sem rInitial) r)
      (f [a1] -> Sem (Concurrency safe : r) (f [b])))
-> ([a1] -> Sem rInitial [b])
-> Sem
     (WithTactics (Concurrency safe) f (Sem rInitial) r)
     (f [a1] -> Sem (Concurrency safe : r) (f [b]))
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse @[] a1 -> Sem rInitial b
f
    Sem r (f x)
-> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x)
forall (e :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]) a.
Sem r a -> Sem (e : r) a
raise (Sem r (f x)
 -> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x))
-> Sem r (f x)
-> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x)
forall a b. (a -> b) -> a -> b
$ Sem (Concurrency safe : r) (f x) -> Sem r (f x)
forall (safe :: ConcurrencySafety) (r :: [(* -> *) -> * -> *]) a.
Sem (Concurrency safe : r) a -> Sem r a
sequentiallyPerformConcurrency (Sem (Concurrency safe : r) (f x) -> Sem r (f x))
-> Sem (Concurrency safe : r) (f x) -> Sem r (f x)
forall a b. (a -> b) -> a -> b
$ f [a1] -> Sem (Concurrency safe : r) (f x)
f [a1] -> Sem (Concurrency safe : r) (f [b])
ftraverse (f [a1] -> Sem (Concurrency safe : r) (f x))
-> f [a1] -> Sem (Concurrency safe : r) (f x)
forall a b. (a -> b) -> a -> b
$ t a1 -> [a1]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t a1
t [a1] -> f () -> f [a1]
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f ()
st
  UnsafePooledMapConcurrentlyN_ Int
_ a1 -> Sem rInitial b
f (t a1
t :: t x) -> do
    f ()
st <- Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f ())
forall (f :: * -> *) (m :: * -> *) (r :: [(* -> *) -> * -> *])
       (e :: (* -> *) -> * -> *).
Sem (WithTactics e f m r) (f ())
getInitialStateT
    f (t a1) -> Sem (Concurrency safe : r) (f ())
ftraverse_ <- (t a1 -> Sem rInitial ())
-> Sem
     (WithTactics (Concurrency safe) f (Sem rInitial) r)
     (f (t a1) -> Sem (Concurrency safe : r) (f ()))
forall a (m :: * -> *) b (e :: (* -> *) -> * -> *) (f :: * -> *)
       (r :: [(* -> *) -> * -> *]).
(a -> m b) -> Sem (WithTactics e f m r) (f a -> Sem (e : r) (f b))
bindT ((t a1 -> Sem rInitial ())
 -> Sem
      (WithTactics (Concurrency safe) f (Sem rInitial) r)
      (f (t a1) -> Sem (Concurrency safe : r) (f ())))
-> (t a1 -> Sem rInitial ())
-> Sem
     (WithTactics (Concurrency safe) f (Sem rInitial) r)
     (f (t a1) -> Sem (Concurrency safe : r) (f ()))
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ @t a1 -> Sem rInitial b
f
    Sem r (f x)
-> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x)
forall (e :: (* -> *) -> * -> *) (r :: [(* -> *) -> * -> *]) a.
Sem r a -> Sem (e : r) a
raise (Sem r (f x)
 -> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x))
-> Sem r (f x)
-> Sem (WithTactics (Concurrency safe) f (Sem rInitial) r) (f x)
forall a b. (a -> b) -> a -> b
$ Sem (Concurrency safe : r) (f x) -> Sem r (f x)
forall (safe :: ConcurrencySafety) (r :: [(* -> *) -> * -> *]) a.
Sem (Concurrency safe : r) a -> Sem r a
sequentiallyPerformConcurrency (Sem (Concurrency safe : r) (f x) -> Sem r (f x))
-> Sem (Concurrency safe : r) (f x) -> Sem r (f x)
forall a b. (a -> b) -> a -> b
$ f (t a1) -> Sem (Concurrency safe : r) (f x)
f (t a1) -> Sem (Concurrency safe : r) (f ())
ftraverse_ (f (t a1) -> Sem (Concurrency safe : r) (f x))
-> f (t a1) -> Sem (Concurrency safe : r) (f x)
forall a b. (a -> b) -> a -> b
$ t a1
t t a1 -> f () -> f (t a1)
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f ()
st