packages feed

legion 0.6.0.0 → 0.7.0.0

raw patch · 14 files changed

+322/−322 lines, 14 files

Files

legion.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                legion-version:             0.6.0.0+version:             0.7.0.0 synopsis:            Distributed, stateful, homogeneous microservice framework. description:         Legion is a framework for writing distributed,                      homogeneous, stateful microservices in Haskell.
src/Network/Legion.hs view
@@ -47,7 +47,7 @@   Indexable(..),   LegionConstraints,   Persistence(..),-  ApplyDelta(..),+  Event(..),   Tag(..),    -- * Other Types@@ -71,7 +71,7 @@   Indexable(indexEntries)) import Network.Legion.PartitionKey (PartitionKey(K, unKey)) import Network.Legion.PartitionState (PartitionPowerState)-import Network.Legion.PowerState (ApplyDelta(apply))+import Network.Legion.PowerState (Event(apply)) import Network.Legion.Runtime (StartupMode(NewCluster, JoinCluster),   forkLegionary, Runtime, makeRequest, search) import Network.Legion.Settings (RuntimeSettings(RuntimeSettings,@@ -115,14 +115,14 @@ -- The only thing required to implement a legion service is to implement -- a few typeclasses and call 'forkLegionary'. The state-aware part of -- your application will live mostly within the request handler, which--- is implemented via a typeclass `ApplyDelta`.+-- is implemented via a typeclass `Event`. -- --- > class ApplyDelta i o s | i s -> o where--- >   apply :: i -> s -> (o, s)+-- > class Event e o s | e -> s o where+-- >   apply :: e -> s -> (o, s) --  -- If you look at 'apply', you will see that it is abstract over the type--- variables @i@, @o@, and @s@.  These are the types your application--- has to fill in. @i@ stands for "input", which is the type of requests+-- variables @e@, @o@, and @s@.  These are the types your application+-- has to fill in. @e@ stands for "event", which is the type of requests -- your application accepts; @o@ stands for "output", which is the type of -- responses your application will generate in response to those requests, -- and @s@ stands for "state", which is the application state that each@@ -131,8 +131,8 @@ -- Implementing a request handler is pretty straight forward, but -- there is a little bit more to it than meets the eye. If you look at -- 'forkLegionary', you will see a constraint named @'LegionConstraints'--- i o s@, which is short-hand for a long list of typeclasses that your--- @i@, @o@, and @s@ types are going to have to implement.+-- e o s@, which is short-hand for a long list of typeclasses that your+-- @e@, @o@, and @s@ types are going to have to implement. -- -- The persistence layer provides the framework with a way to store the -- various partition states. This allows you to choose any number of
src/Network/Legion/Admin.hs view
@@ -44,10 +44,10 @@ {- |   Start the admin service in a background thread. -}-runAdmin :: (LegionConstraints i o s)+runAdmin :: (LegionConstraints e o s)   => Port   -> HostPreference-  -> LIO (Source LIO (AdminMessage i o s))+  -> LIO (Source LIO (AdminMessage e o s)) runAdmin addr host = do     logging <- askLoggerIO     chan <- lift newChan@@ -81,8 +81,8 @@     return (chanToSource chan)   where     send-      :: Chan (AdminMessage i o s)-      -> ((a -> LIO ()) -> AdminMessage i o s)+      :: Chan (AdminMessage e o s)+      -> ((a -> LIO ()) -> AdminMessage e o s)       -> ActionT Text LIO a     send chan msg = lift . lift $ do       mvar <- newEmptyMVar@@ -127,12 +127,12 @@ {- |   The type of messages sent by the admin service. -}-data AdminMessage i o s-  = GetState (NodeState i o s -> LIO ())-  | GetPart PartitionKey (Maybe (PartitionPowerState i o s) -> LIO ())+data AdminMessage e o s+  = GetState (NodeState e o s -> LIO ())+  | GetPart PartitionKey (Maybe (PartitionPowerState e o s) -> LIO ())   | Eject Peer (() -> LIO ()) -instance Show (AdminMessage i o s) where+instance Show (AdminMessage e o s) where   show (GetState _) = "(GetState _)"   show (GetPart k _) = "(GetPart " ++ show k ++ " _)"   show (Eject p _) = "(Eject " ++ show p ++ " _)"
src/Network/Legion/Application.hs view
@@ -14,20 +14,20 @@ import Network.Legion.Index (Indexable) import Network.Legion.PartitionKey (PartitionKey) import Network.Legion.PartitionState (PartitionPowerState)-import Network.Legion.PowerState (ApplyDelta)+import Network.Legion.PowerState (Event)  {- |   This is a more convenient way to write the somewhat unwieldy set of   constraints    > (-  >   ApplyDelta i o s, Default s, Binary i, Binary o, Binary s, Show i,-  >   Show o, Show s, Eq i+  >   Event e o s, Default s, Binary e, Binary o, Binary s, Show e,+  >   Show o, Show s, Eq e   > ) -}-type LegionConstraints i o s = (-    ApplyDelta i o s, Indexable s, Default s, Binary i, Binary o, Binary s,-    Show i, Show o, Show s, Eq i+type LegionConstraints e o s = (+    Event e o s, Indexable s, Default s, Binary e, Binary o, Binary s,+    Show e, Show o, Show s, Eq e   )  @@ -36,10 +36,10 @@   partition states. See 'Network.Legion.newMemoryPersistence' or   'Network.Legion.diskPersistence' if you need to get started quickly. -}-data Persistence i o s = Persistence {-     getState :: PartitionKey -> IO (Maybe (PartitionPowerState i o s)),-    saveState :: PartitionKey -> Maybe (PartitionPowerState i o s) -> IO (),-         list :: Source IO (PartitionKey, PartitionPowerState i o s)+data Persistence e o s = Persistence {+     getState :: PartitionKey -> IO (Maybe (PartitionPowerState e o s)),+    saveState :: PartitionKey -> Maybe (PartitionPowerState e o s) -> IO (),+         list :: Source IO (PartitionKey, PartitionPowerState e o s)       {- ^         List all the keys known to the persistence layer. It is important         that the implementation do the right thing with regard to
src/Network/Legion/Basics.hs view
@@ -33,7 +33,7 @@   A convenient memory-based persistence layer. Good for testing or for   applications (like caches) that don't have durability requirements. -}-newMemoryPersistence :: IO (Persistence i o s)+newMemoryPersistence :: IO (Persistence e o s)  newMemoryPersistence = do     cacheT <- atomically (newTVar Map.empty)@@ -44,9 +44,9 @@       }   where     saveState_-      :: TVar (Map PartitionKey (PartitionPowerState i o s))+      :: TVar (Map PartitionKey (PartitionPowerState e o s))       -> PartitionKey-      -> Maybe (PartitionPowerState i o s)+      -> Maybe (PartitionPowerState e o s)       -> IO ()     saveState_ cacheT key (Just state) =       (atomically . modifyTVar cacheT . insert key) state@@ -55,24 +55,24 @@       (atomically . modifyTVar cacheT . Map.delete) key      fetchState-      :: TVar (Map PartitionKey (PartitionPowerState i o s))+      :: TVar (Map PartitionKey (PartitionPowerState e o s))       -> PartitionKey-      -> IO (Maybe (PartitionPowerState i o s))+      -> IO (Maybe (PartitionPowerState e o s))     fetchState cacheT key = atomically $       lookup key <$> readTVar cacheT      list_-      :: TVar (Map PartitionKey (PartitionPowerState i o s))-      -> Source IO (PartitionKey, PartitionPowerState i o s)+      :: TVar (Map PartitionKey (PartitionPowerState e o s))+      -> Source IO (PartitionKey, PartitionPowerState e o s)     list_ cacheT =       sourceList . Map.toList =<< lift (atomically (readTVar cacheT))   {- | A convenient way to persist partition states to disk.  -}-diskPersistence :: (Binary i, Binary s)+diskPersistence :: (Binary e, Binary s)   => FilePath     -- ^ The directory under which partition states will be stored.-  -> Persistence i o s+  -> Persistence e o s  diskPersistence directory = Persistence {       getState,@@ -80,18 +80,18 @@       list     }   where-    getState :: (Binary i, Binary s)+    getState :: (Binary e, Binary s)       => PartitionKey-      -> IO (Maybe (PartitionPowerState i o s))+      -> IO (Maybe (PartitionPowerState e o s))     getState key =       let path = toPath key in       doesFileExist path >>= bool         (return Nothing)         ((Just . decode . fromStrict) <$> readFile path) -    saveState :: (Binary i, Binary s)+    saveState :: (Binary e, Binary s)       => PartitionKey-      -> Maybe (PartitionPowerState i o s)+      -> Maybe (PartitionPowerState e o s)       -> IO ()     saveState key (Just state) =       writeFile (toPath key) (toStrict (encode state))@@ -101,8 +101,8 @@         (return ())         (removeFile path) -    list :: (Binary i, Binary s)-      => Source IO (PartitionKey, PartitionPowerState i o s)+    list :: (Binary e, Binary s)+      => Source IO (PartitionKey, PartitionPowerState e o s)     list = do         keys <- lift $ readHexList <$> getDirectoryContents directory         sourceList keys =$= fillData
src/Network/Legion/ClusterState.hs view
@@ -37,7 +37,7 @@ import Network.Legion.Distribution (ParticipationDefaults, modify, Peer) import Network.Legion.KeySet (KeySet, full, unions) import Network.Legion.PartitionKey (PartitionKey)-import Network.Legion.PowerState (ApplyDelta(apply))+import Network.Legion.PowerState (Event(apply)) import Network.Legion.Propagation (PropState, PropPowerState) import Network.Socket (SockAddr) import qualified Data.Map as Map@@ -97,7 +97,7 @@   | PeerEjected Peer   deriving (Show, Generic) instance Binary Update-instance ApplyDelta Update () ClusterState where+instance Event Update () ClusterState where   apply (PeerJoined peer addr) cs@ClusterState {peers} =     ((), cs {peers = Map.insert peer addr peers})   apply (Participating peer ks) cs@ClusterState {distribution} =@@ -119,7 +119,7 @@   -> ClusterPropState claimParticipation peer ks =   ClusterPropState-  . P.delta (Participating peer ks)+  . P.event (Participating peer ks)   . unPropState  @@ -130,7 +130,7 @@ new clusterId self addy =   claimParticipation self full   . ClusterPropState-  . P.delta (PeerJoined self (BSockAddr addy))+  . P.event (PeerJoined self (BSockAddr addy))   $ P.new clusterId self (Set.singleton self)  @@ -185,7 +185,7 @@   -> ClusterPropState joinCluster peer addy =   ClusterPropState-  . P.delta (PeerJoined peer addy)+  . P.event (PeerJoined peer addy)   . P.participate peer   . unPropState @@ -196,7 +196,7 @@ eject :: Peer -> ClusterPropState -> ClusterPropState eject peer =   ClusterPropState-  . P.delta (PeerEjected peer)+  . P.event (PeerEjected peer)   . P.disassociate peer   . unPropState 
src/Network/Legion/Distribution.hs view
@@ -163,9 +163,7 @@   -{- |-  The actions that are taken in order to build a balanced cluster.--}+{- | The actions that are taken in order to build a balanced cluster. -} data RebalanceAction   = Invite KeySet   deriving (Show, Generic)
src/Network/Legion/PartitionState.hs view
@@ -13,7 +13,7 @@   initProp,   participating,   getPowerState,-  delta,+  event,   heartbeat,   participate,   projParticipants,@@ -29,7 +29,7 @@ import Data.Time.Clock (UTCTime) import Network.Legion.Distribution (Peer) import Network.Legion.PartitionKey (PartitionKey)-import Network.Legion.PowerState (ApplyDelta)+import Network.Legion.PowerState (Event) import Network.Legion.Propagation (PropState, PropPowerState) import qualified Network.Legion.Propagation as P @@ -43,8 +43,8 @@   You can save these guys to disk in your `Network.Legion.Persistence`   layer by using its `Binary` instance. -}-newtype PartitionPowerState i o s = PartitionPowerState {-    unPowerState :: PropPowerState PartitionKey s Peer i o+newtype PartitionPowerState e o s = PartitionPowerState {+    unPowerState :: PropPowerState PartitionKey s Peer e o   } deriving (Show, Binary)  @@ -52,8 +52,8 @@   A reification of `PropState`, representing the propagation state of the   partition state. -}-newtype PartitionPropState i o s = PartitionPropState {-    unPropState :: PropState PartitionKey s Peer i o+newtype PartitionPropState e o s = PartitionPropState {+    unPropState :: PropState PartitionKey s Peer e o   } deriving (Eq, Show, ToJSON)  @@ -66,18 +66,18 @@ {- |   Get the projected partition state value. -}-ask :: (ApplyDelta i o s) => PartitionPropState i o s -> s+ask :: (Event e o s) => PartitionPropState e o s -> s ask = P.ask . unPropState   {- |   Try to merge two partition states. -}-mergeEither :: (Show i, Show s, ApplyDelta i o s)+mergeEither :: (Show e, Show s, Event e o s)   => Peer-  -> PartitionPowerState i o s-  -> PartitionPropState i o s-  -> Either String (PartitionPropState i o s)+  -> PartitionPowerState e o s+  -> PartitionPropState e o s+  -> Either String (PartitionPropState e o s) mergeEither peer ps prop =   PartitionPropState <$>     P.mergeEither peer (unPowerState ps) (unPropState prop)@@ -89,8 +89,8 @@   state that is applicable after those actions have been taken. -} actions-  :: PartitionPropState i o s-  -> (Set Peer, PartitionPowerState i o s, PartitionPropState i o s)+  :: PartitionPropState e o s+  -> (Set Peer, PartitionPowerState e o s, PartitionPropState e o s) actions prop =   let (peers, ps, newProp) = P.actions (unPropState prop)   in (peers, PartitionPowerState ps, PartitionPropState newProp)@@ -106,7 +106,7 @@     {- ^ self -}   -> Set Peer     {- ^ The default participation. -}-  -> PartitionPropState i o s+  -> PartitionPropState e o s new key self = PartitionPropState . P.new key self  @@ -114,10 +114,10 @@   Initialize a `PartitionPropState` based on the initial underlying   partition power state. -}-initProp :: (ApplyDelta i o s)+initProp :: (Event e o s)   => Peer-  -> PartitionPowerState i o s-  -> PartitionPropState i o s+  -> PartitionPowerState e o s+  -> PartitionPropState e o s initProp self = PartitionPropState . P.initProp self . unPowerState  @@ -125,7 +125,7 @@   Return `True` if the local peer is participating in the partition   power state. -}-participating :: PartitionPropState i o s -> Bool+participating :: PartitionPropState e o s -> Bool participating = P.participating . unPropState  @@ -133,30 +133,30 @@   Get an opaque encapsulation of the partition power state, for   transferring accros the network or whatever. -}-getPowerState :: PartitionPropState i o s -> PartitionPowerState i o s+getPowerState :: PartitionPropState e o s -> PartitionPowerState e o s getPowerState = PartitionPowerState . P.getPowerState . unPropState  -{- | Apply a delta to the partition state.  -}-delta :: (ApplyDelta i o s)-  => i-  -> PartitionPropState i o s-  -> PartitionPropState i o s-delta d = PartitionPropState . P.delta d . unPropState+{- | Apply an event to the partition state.  -}+event :: (Event e o s)+  => e+  -> PartitionPropState e o s+  -> PartitionPropState e o s+event d = PartitionPropState . P.event d . unPropState   {- | Move time forward for the propagation state.  -}-heartbeat :: UTCTime -> PartitionPropState i o s -> PartitionPropState i o s+heartbeat :: UTCTime -> PartitionPropState e o s -> PartitionPropState e o s heartbeat now = PartitionPropState . P.heartbeat now . unPropState   {- |   Allow a participant to join in the distributed nature of the power state. -}-participate :: (ApplyDelta i o s)+participate :: (Event e o s)   => Peer-  -> PartitionPropState i o s-  -> PartitionPropState i o s+  -> PartitionPropState e o s+  -> PartitionPropState e o s participate peer = PartitionPropState . P.participate peer . unPropState  @@ -164,31 +164,31 @@   Return the projected peers which are participating in the partition   state. -}-projParticipants :: PartitionPropState i o s -> Set Peer+projParticipants :: PartitionPropState e o s -> Set Peer projParticipants = P.projParticipants . unPropState   {- |   Get the projected value of a `PartitionPowerState`. -}-projected :: (ApplyDelta i o s) => PartitionPowerState i o s -> s+projected :: (Event e o s) => PartitionPowerState e o s -> s projected = P.projected . unPowerState   {- |   Get the infimum value of a `PartitionPowerState` -}-infimum :: PartitionPowerState i o s -> s+infimum :: PartitionPowerState e o s -> s infimum = P.infimum . unPowerState   {- |   Figure out if this propagation state has any work to do. Return 'True' if all   known propagation work has been completed. The implication here is that the-  only way more work can happen is if new deltas are applied, either directly+  only way more work can happen is if new events are applied, either directly   or via a merge. -}-idle :: PartitionPropState i o s -> Bool+idle :: PartitionPropState e o s -> Bool idle = P.idle . unPropState  
src/Network/Legion/PowerState.hs view
@@ -7,7 +7,7 @@ module Network.Legion.PowerState (   PowerState,   Infimum(..),-  ApplyDelta(..),+  Event(..),   StateId,   new,   merge,@@ -23,7 +23,7 @@   projParticipants,   divergent,   divergences,-  delta,+  event, ) where  import Prelude hiding (null)@@ -43,21 +43,23 @@  {- |   This represents the set of all possible future values of @s@, in a-  distributed, monotonically increasing environment.+  distributed, monotonically increasing environment. The term "power+  state" is chosen to indicate that values of this type represent multiple+  possible values of the underlying user state @s@. -}-data PowerState o s p d r = PowerState {+data PowerState o s p e r = PowerState {      origin :: o,     infimum :: Infimum s p,-     deltas :: Map (StateId p) (Delta p d, Set p)+     events :: Map (StateId p) (Delta p e, Set p)   } deriving (Generic, Show, Eq)-instance (Binary o, Binary s, Binary p, Binary d) => Binary (PowerState o s p d r)-instance (Show o, Show s, Show p, Show d) => ToJSON (PowerState o s p d r) where-  toJSON PowerState {origin, infimum, deltas} = object [+instance (Binary o, Binary s, Binary p, Binary e) => Binary (PowerState o s p e r)+instance (Show o, Show s, Show p, Show e) => ToJSON (PowerState o s p e r) where+  toJSON PowerState {origin, infimum, events} = object [       "origin" .= show origin,       "infimum" .= infimum,-      "deltas" .= Map.fromList [-          (show sid, (show d, Set.map show ps))-          | (sid, (d, ps)) <- Map.toList deltas+      "events" .= Map.fromList [+          (show sid, (show e, Set.map show ps))+          | (sid, (e, ps)) <- Map.toList events         ]     ] @@ -113,28 +115,28 @@ {- |   `Delta` is how we represent mutations to the power state. -}-data Delta p d+data Delta p e   = Join p   | UnJoin p-  | Delta d+  | Event e   deriving (Generic, Show, Eq)-instance (Binary p, Binary d) => Binary (Delta p d)+instance (Binary p, Binary e) => Binary (Delta p e)   {- |-  The class which allows for delta application.+  The class which allows for event application. -}-class ApplyDelta i o s | i s -> o where+class Event e o s | e -> s o where   {- |-    Apply a delta to a state value. *This function MUST be total!!!*+    Apply an event to a state value. *This function MUST be total!!!*   -}-  apply :: i -> s -> (o, s)+  apply :: e -> s -> (o, s)   {- |   Construct a new PowerState with the given origin and initial participants -}-new :: (Default s) => o -> Set p -> PowerState o s p d r+new :: (Default s) => o -> Set p -> PowerState o s p e r new origin participants =   PowerState {       origin,@@ -143,7 +145,7 @@           participants,           stateValue = def         },-      deltas = Map.empty+      events = Map.empty     }  @@ -153,10 +155,10 @@   a lower one. This function is not total. Only `PowerState`s that originated   from the same `new` call can be merged. -}-merge :: (Eq o, ApplyDelta d r s, Ord p, Show o, Show s, Show p, Show d)-  => PowerState o s p d r-  -> PowerState o s p d r-  -> PowerState o s p d r+merge :: (Eq o, Event e r s, Ord p, Show o, Show s, Show p, Show e)+  => PowerState o s p e r+  -> PowerState o s p e r+  -> PowerState o s p e r merge a b = either error id (mergeEither a b)  @@ -164,10 +166,10 @@   Like `merge`, but safe. Returns `Nothing` if the two power states do   not share the same origin. -}-mergeMaybe :: (Eq o, ApplyDelta d r s, Ord p, Show o, Show s, Show p, Show d)-  => PowerState o s p d r-  -> PowerState o s p d r-  -> Maybe (PowerState o s p d r)+mergeMaybe :: (Eq o, Event e r s, Ord p, Show o, Show s, Show p, Show e)+  => PowerState o s p e r+  -> PowerState o s p e r+  -> Maybe (PowerState o s p e r) mergeMaybe a b = either (const Nothing) Just (mergeEither a b)  @@ -175,27 +177,27 @@   Like `mergeMaybe`, but returns a human-decipherable error message of   exactly what went wrong. -}-mergeEither :: (Eq o, ApplyDelta d r s, Ord p, Show o, Show s, Show p, Show d)-  => PowerState o s p d r-  -> PowerState o s p d r-  -> Either String (PowerState o s p d r)+mergeEither :: (Eq o, Event e r s, Ord p, Show o, Show s, Show p, Show e)+  => PowerState o s p e r+  -> PowerState o s p e r+  -> Either String (PowerState o s p e r) mergeEither (PowerState o1 i1 d1) (PowerState o2 i2 d2) | o1 == o2 =     Right . reduce . removeRenegade $ PowerState {         origin = o1,         infimum,-        deltas = removeObsolete (unionWith mergeAcks d1 d2)+        events = removeObsolete (unionWith mergeAcks d1 d2)       }   where     infimum = max i1 i2      {- |-      Obsolete deltas are deltas that are already included in the latest+      Obsolete events are events that are already included in the latest       infimum.     -}     removeObsolete = filterWithKey (\k _ -> k > stateId infimum)      {- |-      Renegade deltas are deltas that originate from a non-participating+      Renegade events are events that originate from a non-participating       peer.  This might happen in a network partition situation, where       the cluster ejected a peer that later reappears on the network,       broadcasting updates.@@ -209,11 +211,11 @@     -}     removeRenegade ps =         ps {-            deltas =+            events =               fromAscList               . filter nonRenegade               . toAscList-              . deltas+              . events               $ ps           }       where@@ -221,7 +223,7 @@         nonRenegade (Sid _ p, _) = p `member` peers         peers = allParticipants ps -    mergeAcks (d, s1) (_, s2) = (d, s1 `union` s2)+    mergeAcks (e, s1) (_, s2) = (e, s1 `union` s2)  mergeEither a b = Left   $ "PowerStates " ++ show a ++ " and " ++ show b ++ " do not share the "@@ -233,25 +235,25 @@   contained in the powerset. The implication is that the participant   __must__ base all future operations on the result of this function. -}-acknowledge :: (ApplyDelta d r s, Ord p)+acknowledge :: (Event e r s, Ord p)   => p-  -> PowerState o s p d r-  -> PowerState o s p d r-acknowledge p ps@PowerState {deltas} =-    reduce ps {deltas = fmap ackOne deltas}+  -> PowerState o s p e r+  -> PowerState o s p e r+acknowledge p ps@PowerState {events} =+    reduce ps {events = fmap ackOne events}   where-    ackOne (d, acks) = (d, Set.insert p acks)+    ackOne (e, acks) = (e, Set.insert p acks)   {- |   Allow a participant to join in the distributed nature of the power state. -}-participate :: (ApplyDelta d r s, Ord p)+participate :: (Event e r s, Ord p)   => p-  -> PowerState o s p d r-  -> PowerState o s p d r-participate p ps@PowerState {deltas} = acknowledge p $ ps {-    deltas = Map.insert (nextId p ps) (Join p, Set.empty) deltas+  -> PowerState o s p e r+  -> PowerState o s p e r+participate p ps@PowerState {events} = acknowledge p $ ps {+    events = Map.insert (nextId p ps) (Join p, Set.empty) events   }  @@ -259,51 +261,51 @@   Indicate that a participant is removing itself from participating in   the distributed power state. -}-disassociate :: (ApplyDelta d r s, Ord p)+disassociate :: (Event e r s, Ord p)   => p-  -> PowerState o s p d r-  -> PowerState o s p d r-disassociate p ps@PowerState {deltas} = acknowledge p $ ps {-    deltas = Map.insert (nextId p ps) (UnJoin p, Set.empty) deltas+  -> PowerState o s p e r+  -> PowerState o s p e r+disassociate p ps@PowerState {events} = acknowledge p $ ps {+    events = Map.insert (nextId p ps) (UnJoin p, Set.empty) events   }   {- |   Introduce a change to the PowerState on behalf of the participant. -}-delta :: (ApplyDelta d r s, Ord p)+event :: (Event e r s, Ord p)   => p-  -> d-  -> PowerState o s p d r-  -> PowerState o s p d r-delta p d ps@PowerState {deltas} = acknowledge p $ ps {-    deltas = Map.insert (nextId p ps) (Delta d, Set.empty) deltas+  -> e+  -> PowerState o s p e r+  -> PowerState o s p e r+event p e ps@PowerState {events} = acknowledge p $ ps {+    events = Map.insert (nextId p ps) (Event e, Set.empty) events   }   {- |   Return the current projected value of the power state. -}-projectedValue :: (ApplyDelta d r s) => PowerState o s p d r -> s-projectedValue PowerState {infimum = Infimum {stateValue}, deltas} =-    foldr (\ i s -> snd (apply i s)) stateValue changes+projectedValue :: (Event e r s) => PowerState o s p e r -> s+projectedValue PowerState {infimum = Infimum {stateValue}, events} =+    foldr (\ e s -> snd (apply e s)) stateValue changes   where-    changes = foldr getDeltas [] (toDescList deltas)-    getDeltas (_, (Delta d, _)) acc = d:acc+    changes = foldr getDeltas [] (toDescList events)+    getDeltas (_, (Event e, _)) acc = e:acc     getDeltas _ acc = acc   {- |   Return the current infimum value of the power state. -}-infimumValue :: PowerState o s p d r -> s+infimumValue :: PowerState o s p e r -> s infimumValue PowerState {infimum = Infimum {stateValue}} = stateValue   {- |   Gets the known participants at the infimum. -}-infimumParticipants :: PowerState o s p d r -> Set p+infimumParticipants :: PowerState o s p e r -> Set p infimumParticipants PowerState {infimum = Infimum {participants}} = participants  @@ -311,12 +313,12 @@   Get all known participants. This includes participants that are   projected for removal. -}-allParticipants :: (Ord p) => PowerState o s p d r -> Set p+allParticipants :: (Ord p) => PowerState o s p e r -> Set p allParticipants PowerState {     infimum = Infimum {participants},-    deltas+    events   } =-    foldr updateParticipants participants (toDescList deltas)+    foldr updateParticipants participants (toDescList events)   where     updateParticipants (_, (Join p, _)) = Set.insert p     updateParticipants _ = id@@ -326,12 +328,12 @@   Get all the projected participants. This does not include participants that   are projected for removal. -}-projParticipants :: (Ord p) => PowerState o s p d r -> Set p+projParticipants :: (Ord p) => PowerState o s p e r -> Set p projParticipants PowerState {     infimum = Infimum {participants},-    deltas+    events   } =-    foldr updateParticipants participants (toDescList deltas)+    foldr updateParticipants participants (toDescList events)   where     updateParticipants (_, (Join p, _)) = Set.insert p     updateParticipants (_, (UnJoin p, _)) = Set.delete p@@ -340,15 +342,15 @@  {- |   Returns the participants that we think might be diverging. In this-  context, a peer is "diverging" if there is a delta that the peer has+  context, a peer is "diverging" if there is an event that the peer has   not acknowledged. -}-divergent :: (Ord p) => PowerState o s p d r -> Set p+divergent :: (Ord p) => PowerState o s p e r -> Set p divergent PowerState {     infimum = Infimum {participants},-    deltas+    events   } =-    accum participants Set.empty (toAscList deltas)+    accum participants Set.empty (toAscList events)   where     {- |       `accum` mnemonics:@@ -373,7 +375,7 @@       in         accum j2 d2 moreDeltas -    accum j d ((_, (Delta _, a)):moreDeltas) =+    accum j d ((_, (Event _, a)):moreDeltas) =       let         d2 = (j \\ a) `union` d       in@@ -381,13 +383,13 @@   {- |-  Return the deltas that are unknown to the specified peer.+  Return the events that are unknown to the specified peer. -}-divergences :: (Ord p) => p -> PowerState o s p d r -> Map (StateId p) d-divergences peer PowerState {deltas} =+divergences :: (Ord p) => p -> PowerState o s p e r -> Map (StateId p) e+divergences peer PowerState {events} =   fromAscList [-    (sid, d)-    | (sid, (Delta d, p)) <- toAscList deltas+    (sid, e)+    | (sid, (Event e, p)) <- toAscList events     , not (peer `member` p)   ] @@ -397,37 +399,37 @@   has enough information to derive a new infimum value. In other words,   this is where garbage collection happens. -}-reduce :: (ApplyDelta d r s, Ord p) => PowerState o s p d r -> PowerState o s p d r+reduce :: (Event e r s, Ord p) => PowerState o s p e r -> PowerState o s p e r reduce ps@PowerState {     infimum = infimum@Infimum {participants, stateValue},-    deltas+    events   } =-    case minViewWithKey deltas of+    case minViewWithKey events of       Nothing -> ps-      Just ((i, (update, acks)), newDeltas) ->+      Just ((sid, (update, acks)), newDeltas) ->         if not . null $ participants \\ acks           then ps           else case update of             Join p -> reduce ps {                 infimum = infimum {-                    stateId = i,+                    stateId = sid,                     participants = Set.insert p participants                   },-                deltas = newDeltas+                events = newDeltas               }             UnJoin p -> reduce ps {                 infimum = infimum {-                    stateId = i,+                    stateId = sid,                     participants = Set.delete p participants                   },-                deltas = newDeltas+                events = newDeltas               }-            Delta d -> reduce ps {+            Event e -> reduce ps {                 infimum = infimum {-                    stateId = i,-                    stateValue = snd (apply d stateValue)+                    stateId = sid,+                    stateValue = snd (apply e stateValue)                   },-                deltas = newDeltas+                events = newDeltas               }  @@ -435,9 +437,9 @@   A utility function that constructs the next `StateId` on behalf of   a participant. -}-nextId :: (Ord p) => p -> PowerState o s p d r -> StateId p-nextId p PowerState {infimum = Infimum {stateId}, deltas} =-  case maximum (stateId:keys deltas) of+nextId :: (Ord p) => p -> PowerState o s p e r -> StateId p+nextId p PowerState {infimum = Infimum {stateId}, events} =+  case maximum (stateId:keys events) of     BottomSid -> Sid 0 p     Sid ord _ -> Sid (succ ord) p 
src/Network/Legion/Propagation.hs view
@@ -12,7 +12,7 @@   mergeMaybe,   mergeEither,   heartbeat,-  delta,+  event,   actions,   new,   initProp,@@ -40,7 +40,7 @@ import Data.Set (member, Set) import Data.Time.Clock (NominalDiffTime, UTCTime, addUTCTime) import Data.Time.Format () -- For `instance Show UTCTime`-import Network.Legion.PowerState (PowerState, divergent, ApplyDelta,+import Network.Legion.PowerState (PowerState, divergent, Event,   acknowledge, projectedValue, StateId) import qualified Data.Map as Map import qualified Data.Set as Set@@ -97,14 +97,14 @@ {- |   Retriev the current projected value of the underlying state. -}-ask :: (ApplyDelta d r s) => PropState o s p d r -> s+ask :: (Event d r s) => PropState o s p d r -> s ask = projectedValue . powerState   {- |   Create a new propagation state based on an existing power state. -}-initProp :: (ApplyDelta d r s, Ord p)+initProp :: (Event d r s, Ord p)   => p   -> PropPowerState o s p d r   -> PropState o s p d r@@ -155,7 +155,7 @@   Like `merge`, but total. `mergeEither` returns a human readable reason why   the foreign powerstate can't be merged in the event of an error. -}-mergeEither :: (Eq o, Ord p, Show o, Show s, Show p, Show d, ApplyDelta d r s)+mergeEither :: (Eq o, Ord p, Show o, Show s, Show p, Show d, Event d r s)   => p   -> PropPowerState o s p d r   -> PropState o s p d r@@ -191,7 +191,7 @@   Like `merge`, but total. `mergeMaybe` returns `Nothing` if the foreign power   state can't be merged. -}-mergeMaybe :: (Eq o, Ord p, Show o, Show s, Show p, Show d, ApplyDelta d r s)+mergeMaybe :: (Eq o, Ord p, Show o, Show s, Show p, Show d, Event d r s)   => p   -> PropPowerState o s p d r   -> PropState o s p d r@@ -208,7 +208,7 @@   precondition is not met, `error` will be called (making this function   non-total). Using `mergeMaybe` or `mergeEither` is recommended. -}-merge :: (Eq o, Ord p, Show o, Show s, Show p, Show d, ApplyDelta d r s)+merge :: (Eq o, Ord p, Show o, Show s, Show p, Show d, Event d r s)   => p   -> PropPowerState o s p d r   -> PropState o s p d r@@ -227,14 +227,14 @@   {- |-  Apply a delta.+  Apply an event. -}-delta :: (Ord p, ApplyDelta d r s)+event :: (Ord p, Event d r s)   => d   -> PropState o s p d r   -> PropState o s p d r-delta d prop@PropState {self, powerState, now} =-  let newPowerState = PS.delta self d powerState+event d prop@PropState {self, powerState, now} =+  let newPowerState = PS.event self d powerState   in prop {       powerState = newPowerState,       peerStates = Map.fromAscList [@@ -292,7 +292,7 @@ {- |   Allow a participant to join in the distributed nature of the power state. -}-participate :: (Ord p, ApplyDelta d r s)+participate :: (Ord p, Event d r s)   => p   -> PropState o s p d r   -> PropState o s p d r@@ -310,7 +310,7 @@ {- |   Eject a participant from the power state. -}-disassociate :: (Ord p, ApplyDelta d r s)+disassociate :: (Ord p, Event d r s)   => p   -> PropState o s p d r   -> PropState o s p d r@@ -326,7 +326,7 @@   {- |-  Return the deltas that are unknown to the specified peer.+  Return the events that are unknown to the specified peer. -} divergences :: (Ord p) => p -> PropState o s p d r -> Map (StateId p) d divergences peer = PS.divergences peer . powerState@@ -368,7 +368,7 @@ {- |   Get the projected value of a PropPowerState. -}-projected :: (ApplyDelta d r s) => PropPowerState o s p d r -> s+projected :: (Event d r s) => PropPowerState o s p d r -> s projected = PS.projectedValue . unPowerState  @@ -382,7 +382,7 @@ {- |   Figure out if this propagation state has any work to do. Return 'True' if all   known propagation work has been completed. The implication here is that the-  only way more work can happen is if new deltas are applied, either directly+  only way more work can happen is if new events are applied, either directly   or via a merge. -} idle :: (Ord p) => PropState o s p d r -> Bool
src/Network/Legion/Runtime.hs view
@@ -82,13 +82,13 @@   request source, and to handle the responses. Unless you know exactly   what you are doing, you probably want to use `forkLegionary` instead. -}-runLegionary :: (LegionConstraints i o s)-  => Persistence i o s+runLegionary :: (LegionConstraints e o s)+  => Persistence e o s     {- ^ The persistence layer used to back the legion framework. -}   -> RuntimeSettings     {- ^ Settings and configuration of the legionframework.  -}   -> StartupMode-  -> Source IO (RequestMsg i o)+  -> Source IO (RequestMsg e o)     {- ^ A source of requests, together with a way to respond to the requets. -}   -> LoggingT IO ()     {-@@ -128,11 +128,11 @@       :: Either           (JoinRequest, JoinResponse -> LIO ())           (Either-            (PeerMessage i o s)+            (PeerMessage e o s)             (Either-              (RequestMsg i o)-              (AdminMessage i o s)))-      -> RuntimeMessage i o s+              (RequestMsg e o)+              (AdminMessage e o s)))+      -> RuntimeMessage e o s     toMessage (Left m) = J m     toMessage (Right (Left m)) = P m     toMessage (Right (Right (Left m))) = R m@@ -142,7 +142,7 @@       Turn an LIO-based conduit into an IO-based conduit, so that it       will work with `merge`.     -}-    loggingC :: ConduitM i o LIO r -> LIO (ConduitM i o IO r)+    loggingC :: ConduitM e o LIO r -> LIO (ConduitM e o IO r)     loggingC c = do       logging <- askLoggerIO       return (transPipe (`runLoggingT` logging) c)@@ -154,18 +154,18 @@   which the request is directed, and a way for the framework to deliver the   response to some interested party. -}-data RequestMsg i o-  = Request PartitionKey i (o -> IO ())+data RequestMsg e o+  = Request PartitionKey e (o -> IO ())   | SearchDispatch SearchTag (Maybe IndexRecord -> IO ())-instance (Show i) => Show (RequestMsg i o) where-  show (Request k i _) = "(Request " ++ show k ++ " " ++ show i ++ " _)"+instance (Show e) => Show (RequestMsg e o) where+  show (Request k e _) = "(Request " ++ show k ++ " " ++ show e ++ " _)"   show (SearchDispatch s _) = "(SearchDispatch " ++ show s ++ " _)"  -messageSink :: (LegionConstraints i o s)-  => Persistence i o s-  -> (RuntimeState i o s, NodeState i o s)-  -> Sink (RuntimeMessage i o s) LIO ()+messageSink :: (LegionConstraints e o s)+  => Persistence e o s+  -> (RuntimeState e o s, NodeState e o s)+  -> Sink (RuntimeMessage e o s) LIO () messageSink persistence states =     await >>= \case       Nothing -> return ()@@ -184,9 +184,9 @@   joined the cluster. -} updatePeers-  :: Persistence i o s-  -> (RuntimeState i o s, NodeState i o s)-  -> LIO (RuntimeState i o s, NodeState i o s)+  :: Persistence e o s+  -> (RuntimeState e o s, NodeState e o s)+  -> LIO (RuntimeState e o s, NodeState e o s) updatePeers persistence (rts, ns) = do   (peers, ns2) <- runSM persistence ns SM.getPeers   newPeers (cm rts) peers@@ -197,10 +197,10 @@   Perform any cluster management actions, and update the state   appropriately. -}-clusterHousekeeping :: (LegionConstraints i o s)-  => Persistence i o s-  -> (RuntimeState i o s, NodeState i o s)-  -> LIO (RuntimeState i o s, NodeState i o s)+clusterHousekeeping :: (LegionConstraints e o s)+  => Persistence e o s+  -> (RuntimeState e o s, NodeState e o s)+  -> LIO (RuntimeState e o s, NodeState e o s) clusterHousekeeping persistence (rts, ns) = do     (actions, ns2) <- runSM persistence ns (         heartbeat@@ -217,9 +217,9 @@   machine. -} clusterAction-  :: ClusterAction i o s-  -> RuntimeState i o s-  -> LIO (RuntimeState i o s)+  :: ClusterAction e o s+  -> RuntimeState e o s+  -> LIO (RuntimeState e o s)  clusterAction     (SM.ClusterMerge peer ps)@@ -241,11 +241,11 @@   state and an initial node state, and producing an updated runtime   state and node state. -}-handleMessage :: (LegionConstraints i o s)-  => Persistence i o s-  -> RuntimeMessage i o s-  -> (RuntimeState i o s, NodeState i o s)-  -> LIO (RuntimeState i o s, NodeState i o s)+handleMessage :: (LegionConstraints e o s)+  => Persistence e o s+  -> RuntimeMessage e o s+  -> (RuntimeState e o s, NodeState e o s)+  -> LIO (RuntimeState e o s, NodeState e o s)  handleMessage {- Partition Merge -}     persistence@@ -355,7 +355,7 @@             ns           )   where-    sendOne :: Peer -> RuntimeState i o s -> LIO (RuntimeState i o s)+    sendOne :: Peer -> RuntimeState e o s -> LIO (RuntimeState e o s)     sendOne peer r@RuntimeState {nextId} = do       send cm peer (PeerMessage self nextId (Search searchTag))       return r {nextId = nextMessageId nextId}@@ -509,9 +509,9 @@   is why this is an @LIO (Source LIO PeerMessage)@ instead of a   @Source LIO PeerMessage@. -}-startPeerListener :: (LegionConstraints i o s)+startPeerListener :: (LegionConstraints e o s)   => RuntimeSettings-  -> LIO (Source LIO (PeerMessage i o s))+  -> LIO (Source LIO (PeerMessage e o s))  startPeerListener RuntimeSettings {peerBindAddr} =     catchAll (do@@ -531,9 +531,9 @@         throwM err       )   where-    acceptLoop :: (LegionConstraints i o s)+    acceptLoop :: (LegionConstraints e o s)       => Socket-      -> Chan (PeerMessage i o s)+      -> Chan (PeerMessage e o s)       -> LIO ()     acceptLoop so inputChan =         catchAll (@@ -575,7 +575,7 @@ makeNodeState   :: RuntimeSettings   -> StartupMode-  -> LIO (Peer, NodeState i o s, Map Peer BSockAddr)+  -> LIO (Peer, NodeState e o s, Map Peer BSockAddr)  makeNodeState RuntimeSettings {peerBindAddr} NewCluster = do   {- Build a brand new node state, for the first node in a cluster. -}@@ -696,21 +696,21 @@   Forks the legion framework in a background thread, and returns a way to   send user requests to it and retrieve the responses to those requests. -  - @__i__@ is the type of request your application will handle. @__i__@ stands-    for __"input"__.+  - @__e__@ is the type of request your application will handle. @__e__@ stands+    for __"event"__.   - @__o__@ is the type of response produced by your application. @__o__@ stands     for __"output"__   - @__s__@ is the type of state maintained by your application. More     precisely, it is the type of the individual partitions that make up     your global application state. @__s__@ stands for __"state"__. -}-forkLegionary :: (LegionConstraints i o s, MonadLoggerIO io)-  => Persistence i o s+forkLegionary :: (LegionConstraints e o s, MonadLoggerIO io)+  => Persistence e o s     {- ^ The persistence layer used to back the legion framework. -}   -> RuntimeSettings     {- ^ Settings and configuration of the legion framework. -}   -> StartupMode-  -> io (Runtime i o)+  -> io (Runtime e o)  forkLegionary persistence settings startupMode = do   logging <- askLoggerIO@@ -742,12 +742,12 @@    'Runtime' is an opaque structure. Use 'makeRequest' to access it. -}-data Runtime i o = Runtime {+data Runtime e o = Runtime {     {- |       Send an application request to the legion runtime, and get back       a response.     -}-    rtMakeRequest :: PartitionKey -> i -> IO o,+    rtMakeRequest :: PartitionKey -> e -> IO o,      {- | Query the index to find a set of partition keys.  -}     rtSearch :: SearchTag -> IO (Maybe IndexRecord)@@ -755,7 +755,7 @@   {- | Send a user request to the legion runtime. -}-makeRequest :: (MonadIO io) => Runtime i o -> PartitionKey -> i -> io o+makeRequest :: (MonadIO io) => Runtime e o -> PartitionKey -> e -> io o makeRequest rt key = liftIO . rtMakeRequest rt key  @@ -763,7 +763,7 @@   Send a search request to the legion runtime. Returns results that are   __strictly greater than__ the provided 'SearchTag'. -}-search :: (MonadIO io) => Runtime i o -> SearchTag -> Source io IndexRecord+search :: (MonadIO io) => Runtime e o -> SearchTag -> Source io IndexRecord search rt tag =   liftIO (rtSearch rt tag) >>= \case     Nothing -> return ()@@ -773,12 +773,12 @@   {- | This is the type of message passed around in the runtime. -}-data RuntimeMessage i o s-  = P (PeerMessage i o s)-  | R (RequestMsg i o)+data RuntimeMessage e o s+  = P (PeerMessage e o s)+  | R (RequestMsg e o)   | J (JoinRequest, JoinResponse -> LIO ())-  | A (AdminMessage i o s)-instance (Show i, Show o, Show s) => Show (RuntimeMessage i o s) where+  | A (AdminMessage e o s)+instance (Show e, Show o, Show s) => Show (RuntimeMessage e o s) where   show (P m) = "(P " ++ show m ++ ")"   show (R m) = "(R " ++ show m ++ ")"   show (J (jr, _)) = "(J (" ++ show jr ++ ", _))"@@ -807,11 +807,11 @@   the reader. It does help simplify the code a little bit because we don't have   to specify some kind of UUID to differentiate otherwise identical searches. -}-data RuntimeState i o s = RuntimeState {+data RuntimeState e o s = RuntimeState {          self :: Peer,     forwarded :: Map MessageId (o -> LIO ()),        nextId :: MessageId,-           cm :: ConnectionManager i o s,+           cm :: ConnectionManager e o s,      searches :: Map                   SearchTag                   (Set Peer, Maybe IndexRecord, [Maybe IndexRecord -> LIO ()])
src/Network/Legion/Runtime/ConnectionManager.hs view
@@ -36,17 +36,17 @@ {- |   A handle on the connection manager -}-data ConnectionManager i o s = C (Chan (Message i o s))-instance Show (ConnectionManager i o s) where+data ConnectionManager e o s = C (Chan (Message e o s))+instance Show (ConnectionManager e o s) where   show _ = "ConnectionManager"   {- |   Create a new connection manager. -}-newConnectionManager :: (Binary i, Binary o, Binary s)+newConnectionManager :: (Binary e, Binary o, Binary s)   => Map Peer BSockAddr-  -> LIO (ConnectionManager i o s)+  -> LIO (ConnectionManager e o s) newConnectionManager initPeers = do     chan <- lift newChan     forkC "connection manager thread" $@@ -55,16 +55,16 @@     newPeers cm initPeers     return cm   where-    manager :: (Binary s, Binary o, Binary i)-      => Chan (Message i o s)-      -> State i o s+    manager :: (Binary s, Binary o, Binary e)+      => Chan (Message e o s)+      -> State e o s       -> LIO ()     manager chan state = lift (readChan chan) >>= handle state >>= manager chan -    handle :: (Binary i, Binary o, Binary s)-      => State i o s-      -> Message i o s-      -> LIO (State i o s)+    handle :: (Binary e, Binary o, Binary s)+      => State e o s+      -> Message e o s+      -> LIO (State e o s)     handle s@S {connections} (NewPeer peer addr) =       case lookup peer connections of         Nothing -> do@@ -85,9 +85,9 @@ {- |   Build a new connection. -}-connection :: (Binary i, Binary o, Binary s)+connection :: (Binary e, Binary o, Binary s)   => SockAddr-  -> LIO (Chan (PeerMessage i o s))+  -> LIO (Chan (PeerMessage e o s))  connection addr = do     chan <- lift newChan@@ -95,8 +95,8 @@       handle chan Nothing     return chan   where-    handle :: (Binary i, Binary o, Binary s)-      => Chan (PeerMessage i o s)+    handle :: (Binary e, Binary o, Binary s)+      => Chan (PeerMessage e o s)       -> Maybe Socket       -> LIO ()     handle chan so =@@ -152,9 +152,9 @@   Send a message to a peer. -} send-  :: ConnectionManager i o s+  :: ConnectionManager e o s   -> Peer-  -> PeerMessage i o s+  -> PeerMessage e o s   -> LIO () send (C chan) peer = lift . writeChan chan . Send peer @@ -163,7 +163,7 @@   Tell the connection manager about a new peer. -} newPeer-  :: ConnectionManager i o s+  :: ConnectionManager e o s   -> Peer   -> SockAddr   -> LIO ()@@ -173,7 +173,7 @@ {- |   Tell the connection manager about all the peers known to the cluster state. -}-newPeers :: ConnectionManager i o s -> Map Peer BSockAddr -> LIO ()+newPeers :: ConnectionManager e o s -> Map Peer BSockAddr -> LIO () newPeers cm peers =     mapM_ oneNewPeer (toList peers)   where@@ -183,17 +183,17 @@ {- |   The internal state of the connection manager. -}-data State i o s = S {-    connections :: Map Peer (Chan (PeerMessage i o s))+data State e o s = S {+    connections :: Map Peer (Chan (PeerMessage e o s))   }   {- |   The types of messages that the ConnectionManager understands. -}-data Message i o s+data Message e o s   = NewPeer Peer SockAddr-  | Send Peer (PeerMessage i o s)+  | Send Peer (PeerMessage e o s)   {- |
src/Network/Legion/Runtime/PeerMessage.hs view
@@ -28,13 +28,13 @@ {- |   The type of messages sent between peers. -}-data PeerMessage i o s = PeerMessage {+data PeerMessage e o s = PeerMessage {        source :: Peer,     messageId :: MessageId,-      payload :: PeerMessagePayload i o s+      payload :: PeerMessagePayload e o s   }   deriving (Generic, Show)-instance (Binary i, Binary o, Binary s) => Binary (PeerMessage i o s)+instance (Binary e, Binary o, Binary s) => Binary (PeerMessage e o s)   {- |@@ -45,15 +45,15 @@   these messages should result in the ejection of that node from the   cluster and the blacklisting of that node so that it can never re-join. -}-data PeerMessagePayload i o s-  = PartitionMerge PartitionKey (PartitionPowerState i o s)-  | ForwardRequest PartitionKey i+data PeerMessagePayload e o s+  = PartitionMerge PartitionKey (PartitionPowerState e o s)+  | ForwardRequest PartitionKey e   | ForwardResponse MessageId o   | ClusterMerge ClusterPowerState   | Search SearchTag   | SearchResponse SearchTag (Maybe IndexRecord)   deriving (Generic, Show)-instance (Binary i, Binary o, Binary s) => Binary (PeerMessagePayload i o s)+instance (Binary e, Binary o, Binary s) => Binary (PeerMessagePayload e o s)   data MessageId = M UUID Word64 deriving (Generic, Show, Eq, Ord)
src/Network/Legion/StateMachine.hs view
@@ -88,7 +88,7 @@ import Network.Legion.LIO (LIO) import Network.Legion.PartitionKey (PartitionKey) import Network.Legion.PartitionState (PartitionPowerState, PartitionPropState)-import Network.Legion.PowerState (ApplyDelta, apply)+import Network.Legion.PowerState (Event, apply) import qualified Data.Conduit.List as CL import qualified Data.Map as Map import qualified Data.Set as Set@@ -102,20 +102,20 @@   This is the portion of the local node state that is not persistence   related. -}-data NodeState i o s = NodeState {+data NodeState e o s = NodeState {              self :: Peer,           cluster :: ClusterPropState,-       partitions :: Map PartitionKey (PartitionPropState i o s),+       partitions :: Map PartitionKey (PartitionPropState e o s),         migration :: KeySet,           nsIndex :: Set IndexRecord   }-instance (Show i, Show s) => Show (NodeState i o s) where+instance (Show e, Show s) => Show (NodeState e o s) where   show = unpack . decodeUtf8 . toStrict . encode {-   The ToJSON instance is mainly for debugging. The Haskell-generated 'Show'   instance is very hard to read. -}-instance (Show i, Show s) => ToJSON (NodeState i o s) where+instance (Show e, Show s) => ToJSON (NodeState e o s) where   toJSON (NodeState self cluster partitions migration nsIndex) =     object [               "self" .= show self,@@ -129,7 +129,7 @@ {- |   Make a new node state. -}-newNodeState :: Peer -> ClusterPropState -> NodeState i o s+newNodeState :: Peer -> ClusterPropState -> NodeState e o s newNodeState self cluster =   NodeState {       self,@@ -150,8 +150,8 @@   if we want to model the global state of the node as a single unit,   we have to do so using a monad. -}-newtype SM i o s a = SM {-    unSM :: ReaderT (Persistence i o s) (StateT (NodeState i o s) LIO) a+newtype SM e o s a = SM {+    unSM :: ReaderT (Persistence e o s) (StateT (NodeState e o s) LIO) a   }   deriving (Functor, Applicative, Monad, MonadLogger, MonadIO) @@ -160,18 +160,18 @@   Run an SM action. -} runSM-  :: Persistence i o s-  -> NodeState i o s-  -> SM i o s a-  -> LIO (a, NodeState i o s)+  :: Persistence e o s+  -> NodeState e o s+  -> SM e o s a+  -> LIO (a, NodeState e o s) runSM p ns action = runStateT (runReaderT (unSM action) p) ns   {- | Handle a user request. -}-userRequest :: (ApplyDelta i o s, Default s, Indexable s)+userRequest :: (Event e o s, Default s, Indexable s)   => PartitionKey-  -> i-  -> SM i o s (UserResponse o)+  -> e+  -> SM e o s (UserResponse o) userRequest key request = SM $ do   NodeState {self, cluster} <- lift get   let owners = C.findPartition key cluster@@ -180,7 +180,7 @@       partition <- unSM $ getPartition key       let         response = fst (apply request (P.ask partition))-        partition2 = P.delta request partition+        partition2 = P.event request partition       unSM $ savePartition key partition2       return (Respond response) @@ -196,11 +196,11 @@   Handle the state transition for a partition merge event. Returns 'Left'   if there is an error, and 'Right' if everything went fine. -}-partitionMerge :: (Show i, Show s, ApplyDelta i o s, Default s, Indexable s)+partitionMerge :: (Show e, Show s, Event e o s, Default s, Indexable s)   => Peer   -> PartitionKey-  -> PartitionPowerState i o s-  -> SM i o s ()+  -> PartitionPowerState e o s+  -> SM e o s () partitionMerge source key foreignPartition = do   partition <- getPartition key   case P.mergeEither source foreignPartition partition of@@ -215,7 +215,7 @@ clusterMerge   :: Peer   -> ClusterPowerState-  -> SM i o s ()+  -> SM e o s () clusterMerge source foreignCluster = SM . lift $ do   nodeState@NodeState {migration, cluster} <- get   case C.mergeEither source foreignCluster cluster of@@ -242,7 +242,7 @@   peer to a partition. This will cause the data to be transfered in the   normal course of propagation. -}-migrate :: (Default s, ApplyDelta i o s, Indexable s) => SM i o s ()+migrate :: (Default s, Event e o s, Indexable s) => SM e o s () migrate = do     NodeState {migration} <- (SM . lift) get     persistence <- SM ask@@ -252,8 +252,8 @@       $$ accum     (SM . lift) $ modify (\ns -> ns {migration = KS.empty})   where-    accum :: (Default s, ApplyDelta i o s, Indexable s)-      => Sink (PartitionKey, PartitionPowerState i o s) (SM i o s) ()+    accum :: (Default s, Event e o s, Indexable s)+      => Sink (PartitionKey, PartitionPowerState e o s) (SM e o s) ()     accum = awaitForever $ \ (key, ps) -> do       NodeState {self, cluster, partitions} <- (lift . SM . lift) get       let@@ -268,7 +268,7 @@   Handle all cluster and partition state propagation actions, and return   an updated node state. -}-propagate :: SM i o s [ClusterAction i o s]+propagate :: SM e o s [ClusterAction e o s] propagate = SM $ do     partitionActions <- getPartitionActions     clusterActions <- unSM getClusterActions@@ -296,7 +296,7 @@         }       return actions -    getClusterActions :: SM i o s [ClusterAction i o s]+    getClusterActions :: SM e o s [ClusterAction e o s]     getClusterActions = SM $ do       ns@NodeState {cluster} <- lift get       let@@ -312,7 +312,7 @@   Figure out if any rebalancing actions must be taken by this node, and kick   them off if so. -}-rebalance :: SM i o s ()+rebalance :: SM e o s () rebalance = SM $ do   ns@NodeState {self, cluster} <- lift get   let@@ -334,7 +334,7 @@   {- | Update all of the propagation states with the current time.  -}-heartbeat :: SM i o s ()+heartbeat :: SM e o s () heartbeat = SM $ do   now <- lift3 getCurrentTime   ns@NodeState {cluster, partitions} <- lift get@@ -348,14 +348,14 @@   {- | Eject a peer from the cluster.  -}-eject :: Peer -> SM i o s ()+eject :: Peer -> SM e o s () eject peer = SM . lift $ do   ns@NodeState {cluster} <- get   put ns {cluster = C.eject peer cluster}   {- | Handle a peer join request.  -}-join :: BSockAddr -> SM i o s (Peer, ClusterPowerState)+join :: BSockAddr -> SM e o s (Peer, ClusterPowerState) join peerAddr = SM $ do   peer <- lift2 newPeer   ns@NodeState {cluster} <- lift get@@ -387,7 +387,7 @@    TODO: implement fastest competitive search. -}-minimumCompleteServiceSet :: SM i o s (Set Peer)+minimumCompleteServiceSet :: SM e o s (Set Peer) minimumCompleteServiceSet = SM $ do   NodeState {cluster} <- lift get   return (D.minimumCompleteServiceSet (C.getDistribution cluster))@@ -397,7 +397,7 @@   Search the index, and return the first record that is __strictly   greater than__ the provided search tag, if such a record exists. -}-search :: SearchTag -> SM i o s (Maybe IndexRecord)+search :: SearchTag -> SM e o s (Maybe IndexRecord) search SearchTag {stTag, stKey = Nothing} = SM $ do   NodeState {nsIndex} <- lift get   return (Set.lookupGE IndexRecord {irTag = stTag, irKey = minBound} nsIndex)@@ -411,9 +411,9 @@   with other nodes. It is up to the runtime system to implement the   actions. -}-data ClusterAction i o s+data ClusterAction e o s   = ClusterMerge Peer ClusterPowerState-  | PartitionMerge Peer PartitionKey (PartitionPowerState i o s)+  | PartitionMerge Peer PartitionKey (PartitionPowerState e o s)   {- |@@ -426,14 +426,14 @@   {- | Get the known peer data from the cluster. -}-getPeers :: SM i o s (Map Peer BSockAddr)+getPeers :: SM e o s (Map Peer BSockAddr) getPeers = SM $ C.getPeers . cluster <$> lift get   {- | Gets a partition state. -}-getPartition :: (Default s, ApplyDelta i o s)+getPartition :: (Default s, Event e o s)   => PartitionKey-  -> SM i o s (PartitionPropState i o s)+  -> SM e o s (PartitionPropState e o s) getPartition key = SM $ do   persistence <- ask   NodeState {self, partitions, cluster} <- lift get@@ -449,10 +449,10 @@   Saves a partition state. This function automatically handles the cache   for active propagations, as well as reindexing of partitions. -}-savePartition :: (Default s, ApplyDelta i o s, Indexable s)+savePartition :: (Default s, Event e o s, Indexable s)   => PartitionKey-  -> PartitionPropState i o s-  -> SM i o s ()+  -> PartitionPropState e o s+  -> SM e o s () savePartition key partition = SM $ do   persistence <- ask   oldTags <- indexEntries . P.ask <$> unSM (getPartition key)