data structure for RealNode holds common config and management data
contributes to #56, #34, #2
This commit is contained in:
parent
df7423ce2e
commit
d293cc05d1
|
@ -16,10 +16,13 @@ main = do
|
|||
-- ToDo: parse and pass config
|
||||
-- probably use `tomland` for that
|
||||
conf <- readConfig
|
||||
-- TODO: first initialise 'RealNode', then the vservers
|
||||
-- ToDo: load persisted caches, bootstrapping nodes …
|
||||
(serverSock, thisNode) <- fediChordInit conf
|
||||
-- currently no masking is necessary, as there is nothing to clean up
|
||||
cacheWriterThread <- forkIO $ cacheWriter thisNode
|
||||
thisNodeSnap <- readTVarIO thisNode
|
||||
realNode <- readTVarIO $ parentRealNode thisNodeSnap
|
||||
-- try joining the DHT using one of the provided bootstrapping nodes
|
||||
let
|
||||
tryJoining (bn:bns) = do
|
||||
|
@ -28,7 +31,7 @@ main = do
|
|||
Left err -> putStrLn ("join error: " <> err) >> tryJoining bns
|
||||
Right joined -> pure $ Right joined
|
||||
tryJoining [] = pure $ Left "Exhausted all bootstrap points for joining."
|
||||
joinedState <- tryJoining $ confBootstrapNodes conf
|
||||
joinedState <- tryJoining $ bootstrapNodes realNode
|
||||
either (\err -> do
|
||||
-- handle unsuccessful join
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ module Hash2Pub.FediChord (
|
|||
, fediChordJoin
|
||||
, fediChordBootstrapJoin
|
||||
, fediMainThreads
|
||||
, RealNode (..)
|
||||
, nodeStateInit
|
||||
, mkServerSocket
|
||||
, mkSendSocket
|
||||
|
@ -90,27 +91,36 @@ import Debug.Trace (trace)
|
|||
-- | initialise data structures, compute own IDs and bind to listening socket
|
||||
-- ToDo: load persisted state, thus this function already operates in IO
|
||||
fediChordInit :: FediChordConf -> IO (Socket, LocalNodeStateSTM)
|
||||
fediChordInit conf = do
|
||||
initialState <- nodeStateInit conf
|
||||
fediChordInit initConf = do
|
||||
let realNode = RealNode {
|
||||
vservers = []
|
||||
, nodeConfig = initConf
|
||||
, bootstrapNodes = confBootstrapNodes initConf
|
||||
}
|
||||
realNodeSTM <- newTVarIO realNode
|
||||
initialState <- nodeStateInit realNodeSTM
|
||||
initialStateSTM <- newTVarIO initialState
|
||||
serverSock <- mkServerSocket (getIpAddr initialState) (getDhtPort initialState)
|
||||
pure (serverSock, initialStateSTM)
|
||||
|
||||
-- | initialises the 'NodeState' for this local node.
|
||||
-- Separated from 'fediChordInit' to be usable in tests.
|
||||
nodeStateInit :: FediChordConf -> IO LocalNodeState
|
||||
nodeStateInit conf = do
|
||||
nodeStateInit :: RealNodeSTM -> IO LocalNodeState
|
||||
nodeStateInit realNodeSTM = do
|
||||
realNode <- readTVarIO realNodeSTM
|
||||
cacheSTM <- newTVarIO initCache
|
||||
q <- atomically newTQueue
|
||||
let
|
||||
conf = nodeConfig realNode
|
||||
vsID = 0
|
||||
containedState = RemoteNodeState {
|
||||
domain = confDomain conf
|
||||
, ipAddr = confIP conf
|
||||
, nid = genNodeID (confIP conf) (confDomain conf) 0
|
||||
, nid = genNodeID (confIP conf) (confDomain conf) $ fromInteger vsID
|
||||
, dhtPort = toEnum $ confDhtPort conf
|
||||
, servicePort = 0
|
||||
, vServerID = 0
|
||||
}
|
||||
, vServerID = vsID
|
||||
}
|
||||
initialState = LocalNodeState {
|
||||
nodeState = containedState
|
||||
, nodeCacheSTM = cacheSTM
|
||||
|
@ -121,6 +131,7 @@ nodeStateInit conf = do
|
|||
, lNumBestNodes = 3
|
||||
, pNumParallelQueries = 2
|
||||
, jEntriesPerSlice = 2
|
||||
, parentRealNode = realNodeSTM
|
||||
}
|
||||
pure initialState
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ module Hash2Pub.FediChordTypes (
|
|||
, LocalNodeState (..)
|
||||
, LocalNodeStateSTM
|
||||
, RemoteNodeState (..)
|
||||
, RealNode (..)
|
||||
, RealNodeSTM
|
||||
, setSuccessors
|
||||
, setPredecessors
|
||||
, NodeCache
|
||||
|
@ -132,6 +134,19 @@ a `localCompare` b
|
|||
wayForwards = getNodeID (b - a)
|
||||
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
|
||||
data RemoteNodeState = RemoteNodeState
|
||||
|
@ -172,6 +187,8 @@ data LocalNodeState = LocalNodeState
|
|||
-- ^ number of parallel sent queries
|
||||
, jEntriesPerSlice :: Int
|
||||
-- ^ number of desired entries per cache slice
|
||||
, parentRealNode :: RealNodeSTM
|
||||
-- ^ the parent node managing this vserver instance
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module FediChordSpec where
|
||||
|
||||
import Control.Concurrent.STM.TVar
|
||||
import Control.Exception
|
||||
import Data.ASN1.Parse (runParseASN1)
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import qualified Data.Set as Set
|
||||
import Data.ASN1.Parse (runParseASN1)
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import qualified Data.Set as Set
|
||||
import Data.Time.Clock.POSIX
|
||||
import Network.Socket
|
||||
import Test.Hspec
|
||||
|
@ -292,11 +293,20 @@ exampleNodeState = RemoteNodeState {
|
|||
}
|
||||
|
||||
exampleLocalNode :: IO LocalNodeState
|
||||
exampleLocalNode = nodeStateInit $ FediChordConf {
|
||||
exampleLocalNode = nodeStateInit =<< (newTVarIO $ RealNode {
|
||||
vservers = []
|
||||
, nodeConfig = exampleFediConf
|
||||
, bootstrapNodes = confBootstrapNodes exampleFediConf
|
||||
})
|
||||
|
||||
|
||||
exampleFediConf :: FediChordConf
|
||||
exampleFediConf = FediChordConf {
|
||||
confDomain = "example.social"
|
||||
, confIP = exampleIp
|
||||
, confDhtPort = 2342
|
||||
}
|
||||
|
||||
exampleNodeDomain :: String
|
||||
exampleNodeDomain = "example.social"
|
||||
exampleVs :: (Integral i) => i
|
||||
|
|
Loading…
Reference in a new issue