summaryrefslogtreecommitdiff
path: root/proto.pod
blob: 2917b5f56d17f8335cc0d7d4a23aa7b938281656 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

=head1 Introduction

This document defines a protocol to link two servers together with the intent
that they become part of the same network. The protocol is run on top of a
reliable bidirectional and stream-oriented connection, such as UNIX sockets or
TCP.




=head1 Handshake

Since the server/client terminoligy is confusing in the context of Tanja, as
this protocol links two I<Servers> with each other, I'll not use those terms in
this document. Instead, we have the I<connecting server> that opens the
connection to the I<listening server>. Which server connected to the other only
matters for the discussion in the handshake part of the protocol, later this
distinction vanishes.

After the connection has been established, the listening server is the first to
send a message.  This message is a space-separated list of parameters, followed
by a newline character (\n).  Parameters may themselves contain multiple items
by separating them with commas. Parameters must be self-describing, the order
in which they appear does not matter. Upon receiving this, the connecting
server then replies with a similar message.

The following is an example handshake, where I<listen> is the listening server
(the one that has been connected to) and I<connect> is the server that started
the connection.

   listen: ver,1,0 ser,json,gob
  connect: ver,1.0 ser,json

Currently defined parameters are:

=over

=item ver

Protocol version, Formatted as a decimal number, followed by a dot and another
decimal number. The first number is the major version and the second the minor.
Minor versions are used for backward-compatible additions to the protocol,
whereas major version changes indicate incompatibilities. If the listening
server supports multiple major versions, it can list these in the same ver
parameter by separating them with a comma. For example: C<ver,1.5,2.3>. Since
minor releases are always backward-compatible, only the highest supported minor
version has to be listed.

The connecting server replies with the version that will be used for the rest
of the connection (e.g. C<ver,1.0>). Most likely this will be the highest
version supported by both servers.

This document describes protocol version C<1.0>, which is currently the only
version available.

=item ser

Serialization format. The listening server may indicate support for multiple
serialization formats separated by a comma. For example C<ser,json,gob>. The
connecting server then decides which format to use and indicates this in the
reply (e.g. C<ser,json>). Accepted serialization formats are defined below.

=back



=head1 Messages

After the handshake, messages are exchanged asynchronously. There is no
distinction anymore between the connecting and listening server. The message
format described here is purely conceptual, see the serialization formats below
for actual encoding of these messages.


=head2 Pattern synchronisation

Each side of the link operates in one of two modes: One in which the sender of
tuples is not aware of the patterns that the receiver is interested in, and one
in which the pattern list of the receiver is synchronised with the sender. The
initial mode is the one without synchronisation of patterns. The side that is
responsible for sending the tuples dictates which mode to use.

I<TODO:> This explanation is awfully vague, and so are the descriptions below.

=over

=item PATTERNSYNC [on|off]

Request the other side of the connection to either enable or disable
synchronisation of its pattern list. If synchronisation is disabled, no
REGISTER or UNREGISTER messages will be sent.

I<TODO:> Note about sending the initial list.

=item REGISTER $pid $pattern

Indicates that the sender of the message is interested in receiving tuples
matching $pattern. $pid is a positive number between 1 and C<2^31-1> and
uniquely identifies this pattern among other patterns registered by the sender.
Id numbers may be re-used after an UNREGISTER has been sent.

When a REGISTER message is received with a $pid that has already been used
before, this should be taken as a sequence of C<UNREGISTER $pid> followed by
the REGISTER command.

=item REGDONE

I<TODO>

=item UNREGISTER $pid

Indicates that the sender of the message is not interested anymore in receiving
tuples matching the pattern that has previously been registered with REGISTER.

An UNREGISTER message with a $pid not known to the receiver (e.g. it has
already been UNREGISTER'ed or has never been REGISTER'ed previously) should be
ignored.

=back


=head2 Tuple communication

=over

=item TUPLE $tid $tuple

Passes a tuple from the sending side to the receiving side. Every tuple is only
sent once, even if the other side has registered multiple patterns for which
the tuple matches.

$tid is a positive number between 0 and C<2^31-1>. If the sending side is not
interested in replies to this tuple (at least, not through a return-path), then
$tid is 0. Any other value is a means to identify the return-path for this
tuple among other active return-paths. This allows replies to this tuple to be
sent back with the REPLY message. Every TUPLE message with $tid>0 B<must> be
replied to either with a corresponding CLOSE or a disconnect. (Note, however,
that there isn't a strict time bound on when this CLOSE has to occur)

=item REPLY $tid $tuple

Send back a reply tuple over the return-path identified with $tid.

=item CLOSE $tid

Close the return-path identified with $tid.

=back

Either side may close the connection at any point. It is not necessary for to
send CLOSE on open return-paths or UNREGISTER for registered patterns when this
happens, things should be cleaned up automatically.




=head1 Serialization formats

=head2 JSON

The JSON serialization format uses the JSON format specified in RFC-4627 and
described on L<http://json.org/>. One exception is made to the specification:
the newline character is not allowed within a message, as it is used as message
delimiter.

=head3 Tuples & patterns

I<TODO>

=head3 Messages

Each message is encoded in a JSON array. The first element in the array
indicates the type of message as an integer, and is followed by any arguments
specific to the message type.  Messages are delimited with a newline.

=over

=item REGISTER

Message type 1. The second element is the $pid, encoded as a number. The third
element is the $pattern.

  [1,14,["object",null,1]]

=item UNREGISTER

Message type 2. The second element is the same as the second element of
REGISTER.

  [2,14]

=item TUPLE

Message type 3. Second element is the $tid, encoded as a number. The third
element is the tuple.

  [3,0,["variable","set","listen",false]]

=item REPLY

Message type 4. Exact same encoding as TUPLE.

  [4,29382,[1]]

=item CLOSE

Message type 5. Second element is the $tid, encoded as a number.

  [5,29382]

=back


=head2 Gob

=head3 Tuples & Patterns

  type Tuple []interface{}
  type Pattern []interface{}

Allowed elements and their behaviour are as defined in the Go implementation.

=head3 Messages

Each message is communicated as a different struct. The type of a I<message> is
therefore C<interface{}>. The following structs are used, corresponding to each
of the messages.

  type msgRegister struct {
    pid     int
    pattern Pattern
  }

  type msgUnregister struct {
    pid int
  }

  type msgTuple struct {
    tid   int
    tuple Tuple
  }

  type msgReply struct {
    tid     int
    pattern Pattern
  }

  type msgClose struct {
    tid int
  }