mirror of https://github.com/voidlizard/hbs2
wip, respect only polled refchans
This commit is contained in:
parent
476ecddb6d
commit
42be590baa
|
@ -105,7 +105,8 @@ instance ForRefChans e => Serialise (RefChanHead e)
|
||||||
|
|
||||||
data RefChanHeadAdapter e m =
|
data RefChanHeadAdapter e m =
|
||||||
RefChanHeadAdapter
|
RefChanHeadAdapter
|
||||||
{ refChanHeadOnHead :: RefChanHeadBlockTran e -> m ()
|
{ refChanHeadOnHead :: RefChanId e -> RefChanHeadBlockTran e -> m ()
|
||||||
|
, refChanHeadSubscribed :: RefChanId e -> m Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
refChanHeadProto :: forall e s m . ( MonadIO m
|
refChanHeadProto :: forall e s m . ( MonadIO m
|
||||||
|
@ -135,9 +136,10 @@ refChanHeadProto self adapter msg = do
|
||||||
|
|
||||||
case msg of
|
case msg of
|
||||||
RefChanHead chan pkt -> do
|
RefChanHead chan pkt -> do
|
||||||
|
guard =<< lift (refChanHeadSubscribed adapter chan)
|
||||||
trace $ "RefChanHead" <+> pretty self <+> pretty (AsBase58 chan)
|
trace $ "RefChanHead" <+> pretty self <+> pretty (AsBase58 chan)
|
||||||
-- FIXME: check-chan-is-listened
|
-- FIXME: check-chan-is-listened
|
||||||
lift $ refChanHeadOnHead adapter pkt
|
lift $ refChanHeadOnHead adapter chan pkt
|
||||||
|
|
||||||
RefChanGetHead _ -> do
|
RefChanGetHead _ -> do
|
||||||
-- прочитать ссылку
|
-- прочитать ссылку
|
||||||
|
|
|
@ -5,33 +5,37 @@ module Brains where
|
||||||
|
|
||||||
import HBS2.Prelude.Plated
|
import HBS2.Prelude.Plated
|
||||||
import HBS2.Clock
|
import HBS2.Clock
|
||||||
|
import HBS2.Data.Types.Refs
|
||||||
import HBS2.Net.Proto
|
import HBS2.Net.Proto
|
||||||
import HBS2.Hash
|
import HBS2.Hash
|
||||||
|
import HBS2.Base58
|
||||||
import HBS2.Net.IP.Addr
|
import HBS2.Net.IP.Addr
|
||||||
|
import HBS2.Net.Auth.Credentials
|
||||||
|
|
||||||
import HBS2.System.Logger.Simple
|
import HBS2.System.Logger.Simple
|
||||||
|
|
||||||
import PeerConfig
|
import PeerConfig
|
||||||
|
|
||||||
import Data.Maybe
|
|
||||||
import Control.Monad
|
|
||||||
import Control.Exception
|
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
import Control.Concurrent.Async
|
import Control.Exception
|
||||||
import Lens.Micro.Platform
|
import Control.Monad
|
||||||
import Data.HashMap.Strict qualified as HashMap
|
|
||||||
import Data.HashMap.Strict (HashMap)
|
|
||||||
import Data.List qualified as List
|
|
||||||
import Data.Cache (Cache)
|
|
||||||
import Data.Cache qualified as Cache
|
|
||||||
import Text.InterpolatedString.Perl6 (qc)
|
|
||||||
import Database.SQLite.Simple
|
import Database.SQLite.Simple
|
||||||
import Database.SQLite.Simple.FromField
|
import Database.SQLite.Simple.FromField
|
||||||
import System.Random (randomRIO)
|
import Data.Cache (Cache)
|
||||||
import Data.Word
|
import Data.Cache qualified as Cache
|
||||||
import Data.Either
|
import Data.Either
|
||||||
|
import Data.HashMap.Strict (HashMap)
|
||||||
|
import Data.HashMap.Strict qualified as HashMap
|
||||||
|
import Data.List qualified as List
|
||||||
|
import Data.Maybe
|
||||||
|
import Data.Text qualified as Text
|
||||||
|
import Data.Word
|
||||||
|
import Lens.Micro.Platform
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
|
import System.Random (randomRIO)
|
||||||
|
import Text.InterpolatedString.Perl6 (qc)
|
||||||
|
import UnliftIO (MonadUnliftIO(..),async,race)
|
||||||
|
|
||||||
data PeerBrainsDb
|
data PeerBrainsDb
|
||||||
|
|
||||||
|
@ -40,6 +44,12 @@ instance HasCfgKey PeerBrainsDb (Maybe String) where
|
||||||
|
|
||||||
class HasBrains e a where
|
class HasBrains e a where
|
||||||
|
|
||||||
|
listPolledRefs :: MonadIO m => a -> String -> m [(PubKey 'Sign (Encryption e), Int)]
|
||||||
|
listPolledRefs _ _ = pure mempty
|
||||||
|
|
||||||
|
isPolledRef :: MonadIO m => a -> PubKey 'Sign (Encryption e) -> m Bool
|
||||||
|
isPolledRef _ _ = pure False
|
||||||
|
|
||||||
onClientTCPConnected :: MonadIO m => a -> PeerAddr e -> Word64 -> m ()
|
onClientTCPConnected :: MonadIO m => a -> PeerAddr e -> Word64 -> m ()
|
||||||
onClientTCPConnected _ _ = const none
|
onClientTCPConnected _ _ = const none
|
||||||
|
|
||||||
|
@ -148,6 +158,8 @@ instance Pretty (Peer e) => HasBrains e NoBrains where
|
||||||
data SomeBrains e = forall a . HasBrains e a => SomeBrains a
|
data SomeBrains e = forall a . HasBrains e a => SomeBrains a
|
||||||
|
|
||||||
instance HasBrains e (SomeBrains e) where
|
instance HasBrains e (SomeBrains e) where
|
||||||
|
listPolledRefs (SomeBrains a) = listPolledRefs @e a
|
||||||
|
isPolledRef (SomeBrains a) = isPolledRef @e a
|
||||||
onClientTCPConnected (SomeBrains a) = onClientTCPConnected @e a
|
onClientTCPConnected (SomeBrains a) = onClientTCPConnected @e a
|
||||||
getClientTCP (SomeBrains a) = getClientTCP @e a
|
getClientTCP (SomeBrains a) = getClientTCP @e a
|
||||||
setActiveTCPSessions (SomeBrains a) = setActiveTCPSessions @e a
|
setActiveTCPSessions (SomeBrains a) = setActiveTCPSessions @e a
|
||||||
|
@ -279,6 +291,23 @@ instance ( Hashable (Peer e)
|
||||||
setReflogProcessed b h = do
|
setReflogProcessed b h = do
|
||||||
updateOP b $ insertReflogProcessed b h
|
updateOP b $ insertReflogProcessed b h
|
||||||
|
|
||||||
|
listPolledRefs brains tp = do
|
||||||
|
liftIO $ do
|
||||||
|
let conn = view brainsDb brains
|
||||||
|
query conn [qc|select ref, interval from poll where type = ?|] (Only tp)
|
||||||
|
<&> fmap (\(r,i) -> (,i) <$> fromStringMay r )
|
||||||
|
<&> catMaybes
|
||||||
|
|
||||||
|
isPolledRef brains ref = do
|
||||||
|
liftIO do
|
||||||
|
let conn = view brainsDb brains
|
||||||
|
query @_ @(Only Int) conn [qc|
|
||||||
|
select 1 from poll
|
||||||
|
where ref = ?
|
||||||
|
limit 1
|
||||||
|
|] ( Only ( show $ pretty (AsBase58 ref) ) )
|
||||||
|
<&> isJust . listToMaybe
|
||||||
|
|
||||||
commitNow :: forall e m . MonadIO m
|
commitNow :: forall e m . MonadIO m
|
||||||
=> BasicBrains e
|
=> BasicBrains e
|
||||||
-> Bool
|
-> Bool
|
||||||
|
@ -690,6 +719,16 @@ newBasicBrains cfg = liftIO do
|
||||||
)
|
)
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
execute_ conn [qc|
|
||||||
|
create table if not exists poll
|
||||||
|
( ref text not null
|
||||||
|
, type text not null
|
||||||
|
, interval int not null
|
||||||
|
, primary key (ref,type)
|
||||||
|
)
|
||||||
|
|]
|
||||||
|
|
||||||
|
|
||||||
BasicBrains <$> newTVarIO mempty
|
BasicBrains <$> newTVarIO mempty
|
||||||
<*> newTVarIO mempty
|
<*> newTVarIO mempty
|
||||||
<*> Cache.newCache (Just (toTimeSpec (30 :: Timeout 'Seconds)))
|
<*> Cache.newCache (Just (toTimeSpec (30 :: Timeout 'Seconds)))
|
||||||
|
@ -697,8 +736,12 @@ newBasicBrains cfg = liftIO do
|
||||||
<*> newTQueueIO
|
<*> newTQueueIO
|
||||||
<*> newTQueueIO
|
<*> newTQueueIO
|
||||||
|
|
||||||
runBasicBrains :: MonadIO m => BasicBrains e -> m ()
|
runBasicBrains :: forall e m . ( e ~ L4Proto, MonadUnliftIO m )
|
||||||
runBasicBrains brains = do
|
=> PeerConfig
|
||||||
|
-> BasicBrains e
|
||||||
|
-> m ()
|
||||||
|
|
||||||
|
runBasicBrains cfg brains = do
|
||||||
|
|
||||||
let pip = view brainsPipeline brains
|
let pip = view brainsPipeline brains
|
||||||
let expire = view brainsExpire brains
|
let expire = view brainsExpire brains
|
||||||
|
@ -725,6 +768,27 @@ runBasicBrains brains = do
|
||||||
pause @'Seconds 60
|
pause @'Seconds 60
|
||||||
updateOP brains (cleanupHashes brains)
|
updateOP brains (cleanupHashes brains)
|
||||||
|
|
||||||
|
trace "runBasicBrains init"
|
||||||
|
|
||||||
|
let (PeerConfig syn) = cfg
|
||||||
|
let polls = catMaybes (
|
||||||
|
[ (tp,n,) <$> fromStringMay @(PubKey 'Sign (Encryption e)) (Text.unpack ref)
|
||||||
|
| ListVal @C (Key "poll" [SymbolVal tp, LitIntVal n, LitStrVal ref]) <- syn
|
||||||
|
] )
|
||||||
|
|
||||||
|
void $ async $ do
|
||||||
|
pause @'Seconds 5
|
||||||
|
forM_ polls $ \(t,mi,x) -> do
|
||||||
|
trace $ "BRAINS: poll" <+> pretty t <+> pretty (AsBase58 x) <+> pretty mi
|
||||||
|
updateOP brains $ do
|
||||||
|
let conn = view brainsDb brains
|
||||||
|
liftIO $ execute conn [qc|
|
||||||
|
insert into poll (ref,type,interval)
|
||||||
|
values (?,?,?)
|
||||||
|
on conflict do update set interval = excluded.interval
|
||||||
|
|] (show $ pretty (AsBase58 x), show $ pretty t, mi)
|
||||||
|
commitNow brains True
|
||||||
|
|
||||||
void $ forever do
|
void $ forever do
|
||||||
pause @'Seconds 15
|
pause @'Seconds 15
|
||||||
ee <- liftIO $ Cache.toList expire
|
ee <- liftIO $ Cache.toList expire
|
||||||
|
|
|
@ -533,7 +533,7 @@ runPeer opts = U.handle (\e -> myException e
|
||||||
|
|
||||||
brains <- newBasicBrains @e conf
|
brains <- newBasicBrains @e conf
|
||||||
|
|
||||||
brainsThread <- async $ runBasicBrains brains
|
brainsThread <- async $ runBasicBrains conf brains
|
||||||
|
|
||||||
denv <- newDownloadEnv brains
|
denv <- newDownloadEnv brains
|
||||||
|
|
||||||
|
@ -564,6 +564,7 @@ runPeer opts = U.handle (\e -> myException e
|
||||||
|
|
||||||
let refChanHeadAdapter = RefChanHeadAdapter
|
let refChanHeadAdapter = RefChanHeadAdapter
|
||||||
{ refChanHeadOnHead = refChanOnHead rce
|
{ refChanHeadOnHead = refChanOnHead rce
|
||||||
|
, refChanHeadSubscribed = isPolledRef @e brains
|
||||||
}
|
}
|
||||||
|
|
||||||
let pexFilt pips = do
|
let pexFilt pips = do
|
||||||
|
|
|
@ -52,8 +52,8 @@ instance Exception DataNotReady
|
||||||
data RefChanWorkerEnv e =
|
data RefChanWorkerEnv e =
|
||||||
RefChanWorkerEnv
|
RefChanWorkerEnv
|
||||||
{ _refChanWorkerEnvDownload :: DownloadEnv e
|
{ _refChanWorkerEnvDownload :: DownloadEnv e
|
||||||
, _refChanWorkerEnvHeadQ :: TQueue (RefChanHeadBlockTran e)
|
, _refChanWorkerEnvHeadQ :: TQueue (RefChanId e, RefChanHeadBlockTran e)
|
||||||
, _refChaWorkerEnvDownload :: TVar (HashMap HashRef TimeSpec) -- таймстемп можно
|
, _refChaWorkerEnvDownload :: TVar (HashMap HashRef (RefChanId e, TimeSpec))
|
||||||
}
|
}
|
||||||
|
|
||||||
makeLenses 'RefChanWorkerEnv
|
makeLenses 'RefChanWorkerEnv
|
||||||
|
@ -67,22 +67,22 @@ refChanWorkerEnv _ de = liftIO $ RefChanWorkerEnv @e de <$> newTQueueIO
|
||||||
<*> newTVarIO mempty
|
<*> newTVarIO mempty
|
||||||
|
|
||||||
|
|
||||||
refChanOnHead :: MonadIO m => RefChanWorkerEnv e -> RefChanHeadBlockTran e -> m ()
|
refChanOnHead :: MonadIO m => RefChanWorkerEnv e -> RefChanId e -> RefChanHeadBlockTran e -> m ()
|
||||||
refChanOnHead env tran = do
|
refChanOnHead env chan tran = do
|
||||||
atomically $ writeTQueue (view refChanWorkerEnvHeadQ env) tran
|
atomically $ writeTQueue (view refChanWorkerEnvHeadQ env) (chan, tran)
|
||||||
|
|
||||||
refChanAddDownload :: forall e m . ( m ~ PeerM e IO
|
refChanAddDownload :: forall e m . ( m ~ PeerM e IO
|
||||||
, MyPeer e
|
, MyPeer e
|
||||||
, Block ByteString ~ ByteString
|
, Block ByteString ~ ByteString
|
||||||
)
|
)
|
||||||
=> RefChanWorkerEnv e -> HashRef -> m ()
|
=> RefChanWorkerEnv e -> RefChanId e -> HashRef -> m ()
|
||||||
refChanAddDownload env r = do
|
refChanAddDownload env chan r = do
|
||||||
penv <- ask
|
penv <- ask
|
||||||
t <- getTimeCoarse
|
t <- getTimeCoarse
|
||||||
withPeerM penv $ withDownload (_refChanWorkerEnvDownload env)
|
withPeerM penv $ withDownload (_refChanWorkerEnvDownload env)
|
||||||
$ processBlock @e (fromHashRef r)
|
$ processBlock @e (fromHashRef r)
|
||||||
|
|
||||||
atomically $ modifyTVar (view refChaWorkerEnvDownload env) (HashMap.insert r t)
|
atomically $ modifyTVar (view refChaWorkerEnvDownload env) (HashMap.insert r (chan,t))
|
||||||
|
|
||||||
checkDownloaded :: forall m . (MonadIO m, HasStorage m, Block ByteString ~ ByteString) => HashRef -> m Bool
|
checkDownloaded :: forall m . (MonadIO m, HasStorage m, Block ByteString ~ ByteString) => HashRef -> m Bool
|
||||||
checkDownloaded hr = do
|
checkDownloaded hr = do
|
||||||
|
@ -146,28 +146,27 @@ refChanWorker env = do
|
||||||
now <- getTimeCoarse
|
now <- getTimeCoarse
|
||||||
|
|
||||||
-- FIXME: consider-timeouts-or-leak-is-possible
|
-- FIXME: consider-timeouts-or-leak-is-possible
|
||||||
rest <- forM all $ \(r,t) -> do
|
rest <- forM all $ \(r,item@(chan,t)) -> do
|
||||||
here <- checkDownloaded r
|
here <- checkDownloaded r
|
||||||
if here then do
|
if here then do
|
||||||
refChanOnHead env (RefChanHeadBlockTran r)
|
refChanOnHead env chan (RefChanHeadBlockTran r)
|
||||||
pure mempty
|
pure mempty
|
||||||
else do
|
else do
|
||||||
-- FIXME: fix-timeout-hardcode
|
-- FIXME: fix-timeout-hardcode
|
||||||
let expired = realToFrac (toNanoSecs $ now - t) / 1e9 > 600
|
let expired = realToFrac (toNanoSecs $ now - t) / 1e9 > 600
|
||||||
if expired then pure mempty else pure [(r,t)]
|
if expired then pure mempty else pure [(r,item)]
|
||||||
|
|
||||||
atomically $ writeTVar (view refChaWorkerEnvDownload env) (HashMap.fromList (mconcat rest))
|
atomically $ writeTVar (view refChaWorkerEnvDownload env) (HashMap.fromList (mconcat rest))
|
||||||
|
|
||||||
-- FIXME: in-parallel?
|
-- FIXME: in-parallel?
|
||||||
refChanHeadMon = do
|
refChanHeadMon = do
|
||||||
forever do
|
forever do
|
||||||
RefChanHeadBlockTran hr <- atomically $ readTQueue (view refChanWorkerEnvHeadQ env)
|
(chan, RefChanHeadBlockTran hr) <- atomically $ readTQueue (view refChanWorkerEnvHeadQ env)
|
||||||
-- debug $ "DROP HEAD UPDATE" <+> pretty (fromRefChanHeadBlockTran tran)
|
|
||||||
|
|
||||||
here <- checkDownloaded hr
|
here <- checkDownloaded hr
|
||||||
|
|
||||||
if not here then do
|
if not here then do
|
||||||
refChanAddDownload env hr
|
refChanAddDownload env chan hr
|
||||||
trace $ "BLOCK IS NOT HERE" <+> pretty hr
|
trace $ "BLOCK IS NOT HERE" <+> pretty hr
|
||||||
else do
|
else do
|
||||||
trace $ "BLOCK IS HERE" <+> pretty hr
|
trace $ "BLOCK IS HERE" <+> pretty hr
|
||||||
|
@ -178,7 +177,7 @@ refChanWorker env = do
|
||||||
case what of
|
case what of
|
||||||
Nothing -> err $ "malformed head block" <+> pretty hr
|
Nothing -> err $ "malformed head block" <+> pretty hr
|
||||||
|
|
||||||
Just (pk,blk) -> do
|
Just (pk,blk) | pk == chan -> do
|
||||||
let rkey = RefChanHeadKey @s pk
|
let rkey = RefChanHeadKey @s pk
|
||||||
|
|
||||||
sto <- getStorage
|
sto <- getStorage
|
||||||
|
@ -205,6 +204,8 @@ refChanWorker env = do
|
||||||
else do
|
else do
|
||||||
debug $ "LEAVING HEAD BLOCK" <+> pretty (v1, v0)
|
debug $ "LEAVING HEAD BLOCK" <+> pretty (v1, v0)
|
||||||
|
|
||||||
|
_ -> debug "not subscribed to this refchan"
|
||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
-- распаковываем блок
|
-- распаковываем блок
|
||||||
-- вытаскиваем ключ из блока?
|
-- вытаскиваем ключ из блока?
|
||||||
|
|
Loading…
Reference in New Issue