This commit is contained in:
Dmitry Zuikov 2023-01-20 08:42:54 +03:00
parent cea8a22e1b
commit 9452e4e5b2
3 changed files with 73 additions and 15 deletions

View File

@ -23,6 +23,8 @@ import Data.Map qualified as Map
import GHC.TypeLits import GHC.TypeLits
import Lens.Micro.Platform import Lens.Micro.Platform
import System.Random qualified as Random import System.Random qualified as Random
import Data.Cache (Cache)
import Data.Cache qualified as Cache
import Codec.Serialise hiding (encode,decode) import Codec.Serialise hiding (encode,decode)
@ -38,6 +40,7 @@ data EngineEnv e = forall bus . ( Messaging bus e ByteString
EngineEnv EngineEnv
{ _peer :: Maybe (Peer e) { _peer :: Maybe (Peer e)
, _self :: Peer e , _self :: Peer e
, _sessions :: Cache (SessionKey e) (SessionData e)
, bus :: bus , bus :: bus
, defer :: Pipeline IO () , defer :: Pipeline IO ()
} }
@ -109,6 +112,27 @@ instance (MonadIO m, HasProtocol e p) => Request e p (EngineM e m) where
let bs = serialise (AnyMessage @e proto (encode msg)) let bs = serialise (AnyMessage @e proto (encode msg))
liftIO $ sendTo b (To p) (From s) bs liftIO $ sendTo b (To p) (From s) bs
instance ( MonadIO m
, Eq (SessionKey e)
, Hashable (SessionKey e)
) => Sessions e (EngineM e m) where
fetch upd def k fn = do
se <- asks (view sessions)
w <- liftIO $ Cache.fetchWithCache se k (const $ pure def)
when upd (liftIO $ Cache.insert se k def)
pure (fn w)
update def k f = do
se <- asks (view sessions)
w <- liftIO $ Cache.fetchWithCache se k (const $ pure def)
liftIO $ Cache.insert se k (f w)
expire k = do
se <- asks (view sessions)
liftIO $ Cache.delete se k
instance (HasProtocol e p, Serialise (Encoded e)) => Response e p (ResponseM e IO) where instance (HasProtocol e p, Serialise (Encoded e)) => Response e p (ResponseM e IO) where
thatPeer _ = asks (view respPeer) thatPeer _ = asks (view respPeer)
@ -140,7 +164,8 @@ newEnv :: forall e bus m . ( Monad m
newEnv p pipe = do newEnv p pipe = do
de <- liftIO $ newPipeline defProtoPipelineSize de <- liftIO $ newPipeline defProtoPipelineSize
pure $ EngineEnv Nothing p pipe de se <- liftIO $ Cache.newCache (Just defCookieTimeout) -- FIXME: some more clever for timeout, i.e. typeclass
pure $ EngineEnv Nothing p se pipe de
runPeer :: forall e m a . ( MonadIO m runPeer :: forall e m a . ( MonadIO m
) )

View File

@ -37,23 +37,43 @@ class Request e p (m :: Type -> Type) | p -> e where
request :: Peer e -> p -> m () request :: Peer e -> p -> m ()
data family SessionKey p :: Type -- we probably can not separate sessions
data family SessionData p :: Type -- by sub-protocol types without
-- really crazy types.
--
-- And if we really need this, it may be done
-- by injecting a protocol type into 'e' or
-- introducing a common ADT for all session types
-- for common 'e' i.e. 'engine' or 'transport'
--
-- So it is that it is.
data family SessionKey e :: Type
data family SessionData e :: Type
class ( Monad m class ( Monad m
, HasProtocol e p , Eq (SessionKey e)
, Eq (SessionKey p) ) => Sessions e m where
) => Sessions e p m | p -> e where
fetch :: SessionData p -- ^ default value in case it's not found -- | Session fetch function.
-> SessionKey p -- ^ session key -- | It will insert a new session, if default value is Just something.
-> (SessionData p -> a ) -- ^ modification function, i.e. lens
fetch :: Bool -- ^ do add new session if not exists
-> SessionData e -- ^ default value in case it's not found
-> SessionKey e -- ^ session key
-> (SessionData e -> a ) -- ^ modification function, i.e. lens
-> m a -> m a
update :: SessionKey p -- ^ session key -- | Session update function
-> (SessionData p -> SessionData p) -- ^ modification function, i.e. lens -- | If will create a new session if it does not exist.
-- | A modified value (or default) value will we saved.
update :: SessionData e -- ^ default value in case it's not found
-> SessionKey e -- ^ session key
-> (SessionData e -> SessionData e) -- ^ modification function, i.e. lens
-> m () -> m ()
expire :: SessionKey e -> m ()
class (KnownNat (ProtocolId p), HasPeer e) => HasProtocol e p | p -> e where class (KnownNat (ProtocolId p), HasPeer e) => HasProtocol e p | p -> e where
type family ProtocolId p = (id :: Nat) | id -> p type family ProtocolId p = (id :: Nat) | id -> p

View File

@ -157,6 +157,19 @@ delSession se l k = liftIO do
expireSession se l = liftIO do expireSession se l = liftIO do
Cache.purgeExpired (view l se) Cache.purgeExpired (view l se)
-- A questionable FIX to avoid "orphans" complains
data Adapted e = Adapted
data instance SessionKey (Adapted e) =
PeerKeyBlock (Hash HbSync)
| PeerKeyCookie (Cookie e)
deriving stock (Eq,Generic)
data instance SessionData (Adapted e) = PeerSession
instance Hashable (SessionKey (Adapted e))
-- newtype FullPeerM m a = RealPeerM { fromRealPeerM :: ReaderT } -- newtype FullPeerM m a = RealPeerM { fromRealPeerM :: ReaderT }