summaryrefslogtreecommitdiff
path: root/Connection.hs
blob: 3287bc1b88d37773d99d0db76e95fd1e867700a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# LANGUAGE DeriveFunctor #-}
module Connection where

import Control.Applicative
import Control.Arrow
import Control.Concurrent.STM
import qualified Data.Map as Map
         ;import Data.Map (Map)

import PingMachine

data Status status
    = Dormant
    | InProgress status
    | Established
 deriving Functor

data Policy
    = RefusingToConnect
    | OpenToConnect
    | TryingToConnect

data Connection status = Connection
    { connStatus    :: STM (Status status)
    , connPolicy    :: STM Policy
    , connPingLogic :: PingMachine
    }
 deriving Functor

data Manager status k = Manager
    { setPolicy    :: k -> Policy -> IO ()
    , connections  :: STM (Map k (Connection status))
    , stringToKey  :: String -> Maybe k
    , showProgress :: status -> String
    , showKey      :: k -> String
    }

showStatus :: Manager status k -> Status status -> String
showStatus mgr Dormant        = "dormant"
showStatus mgr Established    = "established"
showStatus mgr (InProgress s) = "in progress ("++showProgress mgr s++")"


addManagers :: (Ord kA, Ord kB) =>
            Manager statusA kA
            -> Manager statusB kB
            -> Manager (Either statusA statusB) (Either kA kB)
addManagers mgrA mgrB = Manager
    { setPolicy = either (setPolicy mgrA) (setPolicy mgrB)
    , connections = do
        as <- Map.toList <$> connections mgrA
        bs <- Map.toList <$> connections mgrB
        return $ Map.fromList $ map (Left *** fmap Left) as ++ map (Right *** fmap Right) bs
    , stringToKey = \str ->  Left <$> stringToKey mgrA str
                        <|> Right <$> stringToKey mgrB str
    , showProgress = either (showProgress mgrA) (showProgress mgrB)
    , showKey = either (showKey mgrA) (showKey mgrB)
    }