This commit is contained in:
voidlizard 2024-10-13 08:46:23 +03:00
parent 4ed3716d9d
commit e6804415a8
2 changed files with 75 additions and 39 deletions

View File

@ -50,8 +50,10 @@ import Data.HashMap.Strict (HashMap)
import Data.HashMap.Strict qualified as HM import Data.HashMap.Strict qualified as HM
import Data.HashSet (HashSet) import Data.HashSet (HashSet)
import Data.HashSet qualified as HS import Data.HashSet qualified as HS
import Data.List qualified as L
import Data.Maybe import Data.Maybe
import Data.Word import Data.Word
import Data.Hashable
import Codec.Serialise import Codec.Serialise
import Lens.Micro.Platform import Lens.Micro.Platform
import Text.InterpolatedString.Perl6 (qc) import Text.InterpolatedString.Perl6 (qc)
@ -83,8 +85,16 @@ data PolicyDownload s =
PolicyDownload PolicyDownload
{ policyDownloadWhen :: Word64 { policyDownloadWhen :: Word64
, policyDownloadWhat :: SetPolicyPayload s , policyDownloadWhat :: SetPolicyPayload s
, policyDownloadBox :: HashRef
} }
deriving stock Generic deriving stock (Generic)
instance ForMailbox s => Serialise (PolicyDownload s)
deriving instance ForMailbox s => Eq (PolicyDownload s)
instance ForMailbox s => Hashable (PolicyDownload s) where
hashWithSalt s p = hashWithSalt s (serialise p)
data MailboxDowload = data MailboxDowload =
MailboxDowload MailboxDowload
@ -267,45 +277,36 @@ instance ( s ~ Encryption e, e ~ L4Proto
<+> pretty (AsBase58 who) <+> pretty (AsBase58 who)
-- TODO: handle-invalid-policy-error let downloadStatus v = do
-- not "okay" actually maybe1 mbsMailboxHash (okay ()) $ \h -> do
(rcptKey, pNew) <- ContT $ maybe1 (mbsMailboxPolicy >>= unboxSignedBox0) startDownloadStuff me h
(bogusPolicyMessage >> okay ()) atomically $ modifyTVar inMailboxDownloadQ (HM.insert h (MailboxDowload now v))
okay ()
when (coerce rcptKey /= ref) $ lift bogusPolicyMessage >> stop (Right ()) case mbsMailboxPolicy of
Nothing -> downloadStatus Nothing
Just newPolicy -> do
when (sppPolicyVersion pNew > p0) do -- TODO: handle-invalid-policy-error
startDownloadStuff me (sppPolicyRef pNew) -- not "okay" actually
atomically $ modifyTVar inPolicyDownloadQ (HM.insert (sppPolicyRef pNew) (PolicyDownload now pNew))
let v = Just $ max p0 (sppPolicyVersion pNew) (rcptKey, pNew) <- ContT $ maybe1 (unboxSignedBox0 newPolicy)
(bogusPolicyMessage >> okay ())
maybe1 mbsMailboxHash (okay ()) $ \h -> do when (coerce rcptKey /= ref) $ lift bogusPolicyMessage >> stop (Right ())
startDownloadStuff me h
atomically $ modifyTVar inMailboxDownloadQ (HM.insert h (MailboxDowload now v))
okay ()
-- если версия p > версии p0 -- ставим скачиваться, по скачиванию -- обновляем when (sppPolicyVersion pNew > p0) do
-- тут есть какой-то процесс, который должен поллить скачивания, не забываем, startDownloadStuff me (sppPolicyRef pNew)
-- что это довольно затратно (проверка всех блоков)
-- по идее и сообщения-то должны процессить уже с обновленной policy
-- но если этого ждать, то засинкаемся черти когда, однако же
-- надо их начинать качать, как можно раньше. поэтому что?
-- ставим качать policy
-- для каждого сообщения -- ставим качать его
-- наверное, запоминаем версию policy с которой можно процессировать
-- если на момент скачивания сообщения -- policy не достигнуто -- просто его запоминаем
-- если их дофига, а момент так и не наступил --- тогда что?
--
-- наверное, запускаем циклический процесс по обновлению **этого** статуса.
-- сначала качаем policy.
--
-- как скачали -- обновляем, если ок
--
-- если не ок -- то но обновляем? а что тогда
--
okay () mph <- putBlock mpwStorage (serialise newPolicy)
for_ mph $ \ph -> do
let insActually = HM.insert (sppPolicyRef pNew) (PolicyDownload now pNew (HashRef ph))
atomically $ modifyTVar inPolicyDownloadQ insActually
let v = Just $ max p0 (sppPolicyVersion pNew)
downloadStatus v
mailboxGetStatus MailboxProtoWorker{..} ref = do mailboxGetStatus MailboxProtoWorker{..} ref = do
-- TODO: support-policy-ASAP -- TODO: support-policy-ASAP
@ -370,6 +371,18 @@ loadPolicyPayloadFor dbe sto who = do
pure (ha, what) pure (ha, what)
loadPolicyPayloadUnboxed :: forall s m . (ForMailbox s, MonadIO m)
=> DBPipeEnv
-> AnyStorage
-> MailboxRefKey s
-> m (Maybe (SetPolicyPayload s))
loadPolicyPayloadUnboxed dbe sto mbox = do
loadPolicyPayloadFor dbe sto mbox
<&> fmap snd
<&> fmap unboxSignedBox0
<&> join
<&> fmap snd
getMailboxType_ :: (ForMailbox s, MonadIO m) => DBPipeEnv -> MailboxRefKey s -> m (Maybe MailboxType) getMailboxType_ :: (ForMailbox s, MonadIO m) => DBPipeEnv -> MailboxRefKey s -> m (Maybe MailboxType)
getMailboxType_ d r = do getMailboxType_ d r = do
let sql = [qc|select type from mailbox where recipient = ? limit 1|] let sql = [qc|select type from mailbox where recipient = ? limit 1|]
@ -436,7 +449,7 @@ mailboxProtoWorker readConf me@MailboxProtoWorker{..} = do
mFetchQ <- ContT $ withAsync (mailboxFetchQ dbe) mFetchQ <- ContT $ withAsync (mailboxFetchQ dbe)
pDownQ <- ContT $ withAsync policyDownloadQ pDownQ <- ContT $ withAsync (policyDownloadQ dbe)
sDownQ <- ContT $ withAsync stateDownloadQ sDownQ <- ContT $ withAsync stateDownloadQ
@ -535,10 +548,30 @@ mailboxProtoWorker readConf me@MailboxProtoWorker{..} = do
updateRef sto r nref updateRef sto r nref
debug $ yellow "mailbox updated" <+> pretty r <+> pretty nref debug $ yellow "mailbox updated" <+> pretty r <+> pretty nref
policyDownloadQ = do policyDownloadQ dbe = do
forever do
pause @'Seconds 10 -- FIXME: too-often-checks-affect-performance
debug $ red "mailbox: policyDownloadQ" -- $class: performance
let policies = readTVarIO inPolicyDownloadQ
<&> HM.toList
<&> fmap (,10)
polling (Polling 30 30) policies $ \(pk,PolicyDownload{..}) -> do
missed <- findMissedBlocks mpwStorage pk <&> L.null
unless missed do
let mbox = MailboxRefKey (sppMailboxKey policyDownloadWhat)
current <- loadPolicyPayloadUnboxed @s dbe mpwStorage mbox
<&> fmap sppPolicyVersion
<&> fromMaybe 0
let downloaded = sppPolicyVersion policyDownloadWhat
when (downloaded > current) do
-- set policy
pure ()
atomically $ modifyTVar inPolicyDownloadQ (HM.delete pk)
stateDownloadQ = do stateDownloadQ = do
forever do forever do

View File

@ -41,6 +41,9 @@ data SetPolicyPayload s =
} }
deriving stock (Generic) deriving stock (Generic)
-- for Hashable
deriving instance ForMailbox s => Eq (SetPolicyPayload s)
data MailBoxStatusPayload s = data MailBoxStatusPayload s =
MailBoxStatusPayload MailBoxStatusPayload
{ mbsMailboxPayloadNonce :: Word64 { mbsMailboxPayloadNonce :: Word64