summaryrefslogtreecommitdiff
path: root/src/Erebos/Object
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2026-01-25 10:22:04 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2026-01-27 19:45:23 +0100
commit66bfcd8ad4ef16dcd0e287004dc08f8948589bce (patch)
tree337a1658cc4ff76c14254a0d69aafd6c61765a14 /src/Erebos/Object
parent7e0685f049f8981c4f11c3c83caacf85bc855577 (diff)
Deferred object loading
Diffstat (limited to 'src/Erebos/Object')
-rw-r--r--src/Erebos/Object/Deferred.hs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/Erebos/Object/Deferred.hs b/src/Erebos/Object/Deferred.hs
new file mode 100644
index 0000000..1faa85b
--- /dev/null
+++ b/src/Erebos/Object/Deferred.hs
@@ -0,0 +1,57 @@
+module Erebos.Object.Deferred (
+ Deferred,
+ DeferredResult(..),
+
+ deferredRef,
+ deferredLoad,
+
+ deferLoadWithServer,
+) where
+
+import Control.Concurrent.MVar
+import Control.Monad.IO.Class
+
+import Erebos.Identity
+import Erebos.Network
+import Erebos.Object
+import Erebos.Storable
+
+
+data Deferred a = Deferred
+ { deferredRef_ :: RefDigest
+ , deferredServer :: Server
+ , deferredPeers :: [ RefDigest ]
+ }
+
+data DeferredResult a
+ = DeferredLoaded (Stored a)
+ | DeferredInvalid
+ | DeferredFailed
+
+deferredRef :: Deferred a -> RefDigest
+deferredRef = deferredRef_
+
+deferredLoad :: MonadIO m => Storable a => Deferred a -> m (MVar (DeferredResult a))
+deferredLoad Deferred {..} = liftIO $ do
+ mvar <- newEmptyMVar
+ let matchPeer peer =
+ getPeerIdentity peer >>= \case
+ PeerIdentityFull pid -> do
+ return $ any (`elem` identityDigests pid) deferredPeers
+ _ -> return False
+
+ liftIO (findPeer deferredServer matchPeer) >>= \case
+ Just peer -> do
+ requestDataFromPeer peer deferredRef_ $ liftIO . \case
+ DataRequestFulfilled ref -> putMVar mvar $ DeferredLoaded $ wrappedLoad ref
+ DataRequestRejected -> putMVar mvar DeferredFailed
+ DataRequestInvalid -> putMVar mvar DeferredInvalid
+ Nothing -> putMVar mvar DeferredFailed
+ return mvar
+
+deferLoadWithServer :: Storable a => RefDigest -> Server -> [ RefDigest ] -> IO (Deferred a)
+deferLoadWithServer deferredRef_ deferredServer deferredPeers = return Deferred {..}
+
+
+identityDigests :: Foldable f => Identity f -> [ RefDigest ]
+identityDigests pid = map (refDigest . storedRef) $ idDataF =<< unfoldOwners pid