-- ---------------------------------------------------------------------------- {- | Module : Holumbus.Network.PortRegistry.PortRegistryData Copyright : Copyright (C) 2008 Stefan Schmidt License : MIT Maintainer : Stefan Schmidt (stefanschmidt@web.de) Stability : experimental Portability: portable Version : 0.1 This module contains the main datatype for the PortRegistry. -} -- ---------------------------------------------------------------------------- module Holumbus.Network.PortRegistry.PortRegistryData {-# DEPRECATED "this module will be remove in the next release, please use the packages from Holumbus.Distribution.*" #-} ( -- * Datatypes PortRegistryData -- * Creation and Destruction , newPortRegistryData , closePortRegistryData , getPortRegistryRequestPort -- * reexport , setPortRegistry ) where import Control.Concurrent import qualified Data.Map as Map import Network import System.Log.Logger import Holumbus.Common.Threading import Holumbus.Network.Port import Holumbus.Network.Messages import Holumbus.Network.PortRegistry import Holumbus.Network.PortRegistry.Messages localLogger :: String localLogger = "Holumbus.Network.PortRegistry.PortRegistryData" -- ---------------------------------------------------------------------------- -- Datatypes -- ---------------------------------------------------------------------------- -- | The data needed by the PortRegistry data PortRegistryData = PortRegistryData { prd_ServerThreadId :: Thread -- ^ The thread-data of the message-dispatcher thread. , prd_OwnStream :: PortRegistryRequestStream -- ^ The Stream for all incomming messages. , prd_SocketMap :: MVar (Map.Map StreamName SocketId) -- ^ The map storing the port-data (the real registry). } -- ---------------------------------------------------------------------------- -- Creation and Destruction -- ---------------------------------------------------------------------------- -- | Creates a new PortRegistry. newPortRegistryData :: StreamName -> Maybe PortNumber -> IO PortRegistryData newPortRegistryData sn pn = do st <- (newStream STLocal (Just sn) pn)::IO PortRegistryRequestStream mMVar <- newMVar Map.empty sMVar <- newThread let prd = PortRegistryData sMVar st mMVar startRequestDispatcher sMVar st (dispatch prd) return prd -- | Closes the PortRegistry with its streams and threads. closePortRegistryData :: PortRegistryData -> IO () closePortRegistryData prd = do stopRequestDispatcher (prd_ServerThreadId prd) closeStream (prd_OwnStream prd) return () -- | Get the RequestPort of the PortRegistry. -- It can be used to give access to the PortRegistry, eg. you can serialize -- this information and transfer it over the network to grant access to the -- clients. getPortRegistryRequestPort :: PortRegistryData -> IO PortRegistryRequestPort getPortRegistryRequestPort prd = newPortFromStream (prd_OwnStream prd) -- | The main dispatch-function. It handles the incomming messages and reacts. dispatch :: PortRegistryData -> PortRegistryRequestMessage -> PortRegistryResponsePort -> IO () dispatch prd msg replyPort = do case msg of (PRReqRegister sn soid) -> do handleRequest replyPort (registerPort sn soid prd) (\_ -> PRRspSuccess) return () (PRReqUnregister sn) -> do handleRequest replyPort (unregisterPort sn prd) (\_ -> PRRspSuccess) return () (PRReqLookup sn) -> do handleRequest replyPort (lookupPort sn prd) (\soid -> PRRspLookup soid) return () (PRReqGetPorts) -> do handleRequest replyPort (getPorts prd) (\ls -> PRRspGetPorts ls) return () _ -> do infoM localLogger $ "dispatch: unknown request " ++ show msg handleRequest replyPort (return ()) (\_ -> PRRspUnknown) -- ---------------------------------------------------------------------------- -- Typeclass instanciation (PortRegistry) -- ---------------------------------------------------------------------------- -- The PortRegistry-typeclass instanciation for the PortRegistryData. instance PortRegistry PortRegistryData where registerPort sn soid prd = do infoM localLogger $ "register: " ++ sn ++ " - at: " ++ show soid modifyMVar (prd_SocketMap prd) $ \sm -> return (Map.insert sn soid sm, ()) unregisterPort sn prd = do infoM localLogger $ "unregister: " ++ sn modifyMVar (prd_SocketMap prd) $ \sm -> return (Map.delete sn sm, ()) lookupPort sn prd = do infoM localLogger $ "looking up: " ++ sn soid <- withMVar (prd_SocketMap prd) $ \sm -> return (Map.lookup sn sm) infoM localLogger $ "result for: " ++ sn ++ " -> " ++ show soid return soid getPorts prd = do infoM localLogger $ "getting all ports" withMVar (prd_SocketMap prd) $ \sm -> return (Map.toList sm)