module Main where import Control.Concurrent import Control.Concurrent.Async import Control.Concurrent.STM import Control.Concurrent.STM.TVar import Control.Exception import Data.Either import Data.IP (IPv6, toHostAddress6) import System.Environment import Hash2Pub.FediChord import Hash2Pub.FediChordTypes import Hash2Pub.PostService (PostService (..)) main :: IO () main = do -- ToDo: parse and pass config -- probably use `tomland` for that (fConf, sConf) <- readConfig -- ToDo: load persisted caches, bootstrapping nodes … (fediThreads, thisNode) <- fediChordInit fConf (runService sConf :: DHT d => d -> IO (PostService d)) -- wait for all DHT threads to terminate, this keeps the main thread running wait fediThreads readConfig :: IO (FediChordConf, ServiceConf) readConfig = do confDomainString : ipString : portString : servicePortString : speedupString : loadBalancingEnabled : remainingArgs <- getArgs -- allow starting the initial node without bootstrapping info to avoid -- waiting for timeout let speedup = read speedupString statsEvalD = 120 * 10^6 `div` speedup confBootstrapNodes' = case remainingArgs of bootstrapHost : bootstrapPortString : _ -> [(bootstrapHost, read bootstrapPortString)] _ -> [] fConf = FediChordConf { confDomain = confDomainString , confIP = toHostAddress6 . read $ ipString , confDhtPort = read portString , confBootstrapNodes = confBootstrapNodes' , confStabiliseInterval = 80 * 10^6 , confBootstrapSamplingInterval = 180 * 10^6 `div` speedup , confMaxLookupCacheAge = 300 / fromIntegral speedup , confJoinAttemptsInterval = 60 * 10^6 `div` speedup , confMaxNodeCacheAge = 600 / fromIntegral speedup , confResponsePurgeAge = 60 / fromIntegral speedup , confRequestTimeout = 5 * 10^6 `div` speedup , confRequestRetries = 3 , confEnableKChoices = loadBalancingEnabled /= "off" , confKChoicesOverload = 0.9 , confKChoicesUnderload = 0.1 , confKChoicesMaxVS = 8 , confKChoicesRebalanceInterval = round (realToFrac statsEvalD * 1.1 :: Double) } sConf = ServiceConf { confSubscriptionExpiryTime = 24*3600 / fromIntegral speedup , confServicePort = read servicePortString , confServiceHost = confDomainString , confLogfilePath = "../simulationData/logs/" <> confDomainString <> ".log" , confSpeedupFactor = speedup , confStatsEvalDelay = statsEvalD } pure (fConf, sConf)