data structure for RealNode holds common config and management data

contributes to #56, #34, #2
This commit is contained in:
Trolli Schmittlauch 2020-07-07 17:34:42 +02:00
parent df7423ce2e
commit d293cc05d1
4 changed files with 55 additions and 14 deletions

View file

@ -16,10 +16,13 @@ main = do
-- ToDo: parse and pass config -- ToDo: parse and pass config
-- probably use `tomland` for that -- probably use `tomland` for that
conf <- readConfig conf <- readConfig
-- TODO: first initialise 'RealNode', then the vservers
-- ToDo: load persisted caches, bootstrapping nodes … -- ToDo: load persisted caches, bootstrapping nodes …
(serverSock, thisNode) <- fediChordInit conf (serverSock, thisNode) <- fediChordInit conf
-- currently no masking is necessary, as there is nothing to clean up -- currently no masking is necessary, as there is nothing to clean up
cacheWriterThread <- forkIO $ cacheWriter thisNode cacheWriterThread <- forkIO $ cacheWriter thisNode
thisNodeSnap <- readTVarIO thisNode
realNode <- readTVarIO $ parentRealNode thisNodeSnap
-- try joining the DHT using one of the provided bootstrapping nodes -- try joining the DHT using one of the provided bootstrapping nodes
let let
tryJoining (bn:bns) = do tryJoining (bn:bns) = do
@ -28,7 +31,7 @@ main = do
Left err -> putStrLn ("join error: " <> err) >> tryJoining bns Left err -> putStrLn ("join error: " <> err) >> tryJoining bns
Right joined -> pure $ Right joined Right joined -> pure $ Right joined
tryJoining [] = pure $ Left "Exhausted all bootstrap points for joining." tryJoining [] = pure $ Left "Exhausted all bootstrap points for joining."
joinedState <- tryJoining $ confBootstrapNodes conf joinedState <- tryJoining $ bootstrapNodes realNode
either (\err -> do either (\err -> do
-- handle unsuccessful join -- handle unsuccessful join

View file

@ -41,6 +41,7 @@ module Hash2Pub.FediChord (
, fediChordJoin , fediChordJoin
, fediChordBootstrapJoin , fediChordBootstrapJoin
, fediMainThreads , fediMainThreads
, RealNode (..)
, nodeStateInit , nodeStateInit
, mkServerSocket , mkServerSocket
, mkSendSocket , mkSendSocket
@ -90,26 +91,35 @@ import Debug.Trace (trace)
-- | initialise data structures, compute own IDs and bind to listening socket -- | initialise data structures, compute own IDs and bind to listening socket
-- ToDo: load persisted state, thus this function already operates in IO -- ToDo: load persisted state, thus this function already operates in IO
fediChordInit :: FediChordConf -> IO (Socket, LocalNodeStateSTM) fediChordInit :: FediChordConf -> IO (Socket, LocalNodeStateSTM)
fediChordInit conf = do fediChordInit initConf = do
initialState <- nodeStateInit conf let realNode = RealNode {
vservers = []
, nodeConfig = initConf
, bootstrapNodes = confBootstrapNodes initConf
}
realNodeSTM <- newTVarIO realNode
initialState <- nodeStateInit realNodeSTM
initialStateSTM <- newTVarIO initialState initialStateSTM <- newTVarIO initialState
serverSock <- mkServerSocket (getIpAddr initialState) (getDhtPort initialState) serverSock <- mkServerSocket (getIpAddr initialState) (getDhtPort initialState)
pure (serverSock, initialStateSTM) pure (serverSock, initialStateSTM)
-- | initialises the 'NodeState' for this local node. -- | initialises the 'NodeState' for this local node.
-- Separated from 'fediChordInit' to be usable in tests. -- Separated from 'fediChordInit' to be usable in tests.
nodeStateInit :: FediChordConf -> IO LocalNodeState nodeStateInit :: RealNodeSTM -> IO LocalNodeState
nodeStateInit conf = do nodeStateInit realNodeSTM = do
realNode <- readTVarIO realNodeSTM
cacheSTM <- newTVarIO initCache cacheSTM <- newTVarIO initCache
q <- atomically newTQueue q <- atomically newTQueue
let let
conf = nodeConfig realNode
vsID = 0
containedState = RemoteNodeState { containedState = RemoteNodeState {
domain = confDomain conf domain = confDomain conf
, ipAddr = confIP conf , ipAddr = confIP conf
, nid = genNodeID (confIP conf) (confDomain conf) 0 , nid = genNodeID (confIP conf) (confDomain conf) $ fromInteger vsID
, dhtPort = toEnum $ confDhtPort conf , dhtPort = toEnum $ confDhtPort conf
, servicePort = 0 , servicePort = 0
, vServerID = 0 , vServerID = vsID
} }
initialState = LocalNodeState { initialState = LocalNodeState {
nodeState = containedState nodeState = containedState
@ -121,6 +131,7 @@ nodeStateInit conf = do
, lNumBestNodes = 3 , lNumBestNodes = 3
, pNumParallelQueries = 2 , pNumParallelQueries = 2
, jEntriesPerSlice = 2 , jEntriesPerSlice = 2
, parentRealNode = realNodeSTM
} }
pure initialState pure initialState

View file

@ -13,6 +13,8 @@ module Hash2Pub.FediChordTypes (
, LocalNodeState (..) , LocalNodeState (..)
, LocalNodeStateSTM , LocalNodeStateSTM
, RemoteNodeState (..) , RemoteNodeState (..)
, RealNode (..)
, RealNodeSTM
, setSuccessors , setSuccessors
, setPredecessors , setPredecessors
, NodeCache , NodeCache
@ -132,6 +134,19 @@ a `localCompare` b
wayForwards = getNodeID (b - a) wayForwards = getNodeID (b - a)
wayBackwards = getNodeID (a - b) wayBackwards = getNodeID (a - b)
-- | Data for managing the virtual server nodes of this real node.
-- Also contains shared data and config values.
-- TODO: more data structures for k-choices bookkeeping
data RealNode = RealNode
{ vservers :: [LocalNodeStateSTM]
-- ^ references to all active versers
, nodeConfig :: FediChordConf
-- ^ holds the initial configuration read at program start
, bootstrapNodes :: [(String, PortNumber)]
-- ^ nodes to be used as bootstrapping points, new ones learned during operation
}
type RealNodeSTM = TVar RealNode
-- | represents a node and all its important state -- | represents a node and all its important state
data RemoteNodeState = RemoteNodeState data RemoteNodeState = RemoteNodeState
@ -172,6 +187,8 @@ data LocalNodeState = LocalNodeState
-- ^ number of parallel sent queries -- ^ number of parallel sent queries
, jEntriesPerSlice :: Int , jEntriesPerSlice :: Int
-- ^ number of desired entries per cache slice -- ^ number of desired entries per cache slice
, parentRealNode :: RealNodeSTM
-- ^ the parent node managing this vserver instance
} }
deriving (Show, Eq) deriving (Show, Eq)

View file

@ -1,6 +1,7 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module FediChordSpec where module FediChordSpec where
import Control.Concurrent.STM.TVar
import Control.Exception import Control.Exception
import Data.ASN1.Parse (runParseASN1) import Data.ASN1.Parse (runParseASN1)
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
@ -292,11 +293,20 @@ exampleNodeState = RemoteNodeState {
} }
exampleLocalNode :: IO LocalNodeState exampleLocalNode :: IO LocalNodeState
exampleLocalNode = nodeStateInit $ FediChordConf { exampleLocalNode = nodeStateInit =<< (newTVarIO $ RealNode {
vservers = []
, nodeConfig = exampleFediConf
, bootstrapNodes = confBootstrapNodes exampleFediConf
})
exampleFediConf :: FediChordConf
exampleFediConf = FediChordConf {
confDomain = "example.social" confDomain = "example.social"
, confIP = exampleIp , confIP = exampleIp
, confDhtPort = 2342 , confDhtPort = 2342
} }
exampleNodeDomain :: String exampleNodeDomain :: String
exampleNodeDomain = "example.social" exampleNodeDomain = "example.social"
exampleVs :: (Integral i) => i exampleVs :: (Integral i) => i