summaryrefslogtreecommitdiff
path: root/Assistant/Types/NetMessager.hs
blob: 6974cf57df7c1d10afee84449c9a4ed2bb3492e4 (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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
{- git-annex assistant out of band network messager types
 -
 - Copyright 2012 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Assistant.Types.NetMessager where

import Common.Annex
import Assistant.Pairing

import Data.Text (Text)
import Control.Concurrent.STM
import Control.Concurrent.MSampleVar
import Data.ByteString (ByteString)
import Data.Set as S

{- Messages that can be sent out of band by a network messager. -}
data NetMessage 
	-- indicate that pushes have been made to the repos with these uuids
	= NotifyPush [UUID]
	-- requests other clients to inform us of their presence
	| QueryPresence
	-- notification about a stage in the pairing process,
	-- involving a client, and a UUID.
	| PairingNotification PairStage ClientID UUID
	-- request that a git push be sent over the out of band network
	| PushRequest ClientID
	-- indicates that a push is starting
	| StartingPush ClientID
	-- a chunk of output of git receive-pack
	| ReceivePackOutput ClientID ByteString
	-- a chuck of output of git send-pack
	| SendPackOutput ClientID ByteString
	-- sent when git receive-pack exits, with its exit code
	| ReceivePackDone ClientID ExitCode
	deriving (Show, Eq, Ord)

{- Something used to identify the client, or clients to send the message to. -}
type ClientID = Text

getClientID :: NetMessage -> Maybe ClientID
getClientID (NotifyPush _) = Nothing
getClientID QueryPresence = Nothing
getClientID (PairingNotification _ cid _) = Just cid
getClientID (PushRequest cid) = Just cid
getClientID (StartingPush cid) = Just cid
getClientID (ReceivePackOutput cid _) = Just cid
getClientID (SendPackOutput cid _) = Just cid
getClientID (ReceivePackDone cid _) = Just cid

data NetMessager = NetMessager
	-- outgoing messages
	{ netMessages :: TChan (NetMessage)
	-- only one push can be running at a time, and this tracks it
	, netMessagerPushRunning :: TMVar (PushRunning)
	-- incoming messages relating to the currently running push
	, netMessagesPush :: TChan (NetMessage)
	-- incoming push messages that have been deferred to be processed later
	, netMessagesDeferredPush :: TMVar (S.Set NetMessage)
	-- write to this to restart the net messager
	, netMessagerRestart :: MSampleVar ()
	}

data PushRunning = NoPushRunning | SendPushRunning ClientID | ReceivePushRunning ClientID
	deriving (Eq)

newNetMessager :: IO NetMessager
newNetMessager = NetMessager
	<$> atomically newTChan
	<*> atomically (newTMVar NoPushRunning)
	<*> atomically newTChan
	<*> atomically (newTMVar S.empty)
	<*> newEmptySV