main server thread structure
This commit is contained in:
parent
b4ecf8b0aa
commit
61818c58a9
|
@ -39,6 +39,7 @@ module Hash2Pub.FediChord (
|
|||
, fediChordInit
|
||||
, fediChordJoin
|
||||
, fediChordBootstrapJoin
|
||||
, fediMainThreads
|
||||
, nodeStateInit
|
||||
, mkServerSocket
|
||||
, mkSendSocket
|
||||
|
@ -52,9 +53,11 @@ import qualified Data.Map.Strict as Map
|
|||
import Data.Maybe (fromMaybe, isJust, mapMaybe)
|
||||
import qualified Data.Set as Set
|
||||
import Data.Time.Clock.POSIX
|
||||
import Network.Socket
|
||||
import Network.Socket hiding (recv, recvFrom, send, sendTo)
|
||||
import Network.Socket.ByteString
|
||||
|
||||
-- for hashing and ID conversion
|
||||
import Control.Concurrent.Async
|
||||
import Control.Concurrent.STM
|
||||
import Control.Concurrent.STM.TQueue
|
||||
import Control.Monad (forever)
|
||||
|
@ -169,3 +172,53 @@ cacheWriter ns = do
|
|||
refModifier :: NodeCache -> (NodeCache, ())
|
||||
refModifier nc = (f nc, ())
|
||||
atomicModifyIORef' (nodeCacheRef ns) refModifier
|
||||
|
||||
-- | Receives UDP packets and passes them to other threads via the given TQueue.
|
||||
-- Shall be used as the single receiving thread on the server socket, as multiple
|
||||
-- threads blocking on the same socket degrades performance.
|
||||
recvThread :: Socket -- ^ server socket to receive packets from
|
||||
-> TQueue (BS.ByteString, SockAddr) -- ^ receive queue
|
||||
-> IO ()
|
||||
recvThread sock recvQ = forever $ do
|
||||
packet <- recvFrom sock 65535
|
||||
atomically $ writeTQueue recvQ packet
|
||||
|
||||
-- | Only thread to send data it gets from a TQueue through the server socket.
|
||||
sendThread :: Socket -- ^ server socket used for sending
|
||||
-> TQueue (BS.ByteString, SockAddr) -- ^ send queue
|
||||
-> IO ()
|
||||
sendThread sock sendQ = forever $ do
|
||||
(packet, addr) <- atomically $ readTQueue sendQ
|
||||
sendAllTo sock packet addr
|
||||
|
||||
-- | Sets up and manages the main server threads of FediChord
|
||||
fediMainThreads :: Socket -> LocalNodeState -> IO ()
|
||||
fediMainThreads sock ns = do
|
||||
sendQ <- newTQueueIO
|
||||
recvQ <- newTQueueIO
|
||||
-- concurrently launch all handler threads, if one of them throws an exception
|
||||
-- all get cancelled
|
||||
concurrently_
|
||||
(fediMessageHandler sendQ recvQ ns) $
|
||||
concurrently
|
||||
(sendThread sock sendQ)
|
||||
(recvThread sock recvQ)
|
||||
|
||||
|
||||
-- | Wait for messages, deserialise them, manage parts and acknowledgement status,
|
||||
-- and pass them to their specific handling function.
|
||||
fediMessageHandler :: TQueue (BS.ByteString, SockAddr) -- ^ send queue
|
||||
-> TQueue (BS.ByteString, SockAddr) -- ^ receive queue
|
||||
-> LocalNodeState -- ^ acting NodeState
|
||||
-> IO ()
|
||||
fediMessageHandler sendQ recvQ ns = forever $ do
|
||||
-- wait for incoming messages
|
||||
-- newMsg <- deserialiseMessage <$> recvFrom sock
|
||||
-- either (\_ ->
|
||||
-- -- ignore invalid messages
|
||||
-- pure ()
|
||||
-- )
|
||||
-- (\aMsg ->
|
||||
-- case aMsg of
|
||||
-- aRequest@Request{} -> handleRequest
|
||||
pure ()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module Main where
|
||||
|
||||
import Control.Concurrent
|
||||
import Control.Concurrent.Async
|
||||
import Control.Exception
|
||||
import Data.Either
|
||||
import Data.IP (IPv6, toHostAddress6)
|
||||
|
@ -28,15 +29,17 @@ main = do
|
|||
Right joined -> pure $ Right joined
|
||||
tryJoining [] = pure $ Left "Exhausted all bootstrap points for joining."
|
||||
joinedState <- tryJoining $ confBootstrapNodes conf
|
||||
either (\err ->
|
||||
either (\err -> do
|
||||
-- handle unsuccessful join
|
||||
|
||||
putStrLn $ err <> " Error joining, start listening for incoming requests anyways"
|
||||
wait =<< async (fediMainThreads serverSock thisNode)
|
||||
-- TODO: periodic retry
|
||||
)
|
||||
(\joinedNS ->
|
||||
(\joinedNS -> do
|
||||
-- launch main eventloop with successfully joined state
|
||||
putStrLn ("successful join at " <> (show . getNid $ joinedNS))
|
||||
wait =<< async (fediMainThreads serverSock thisNode)
|
||||
)
|
||||
joinedState
|
||||
-- stop main thread from terminating during development
|
||||
|
|
Loading…
Reference in a new issue