summaryrefslogtreecommitdiff
path: root/proto.pod
blob: 5edbc6fed3d9c212717419f03e1fdfa8aee5ed11 (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

Objective: Connect two (or more) Tanja servers together.

Multiple serialization formats: json, gob and possibly others.

Assumes a point-to-point connection-based transport mechanism (e.g. UNIX
sockets and TCP).



=head1 HANDSHAKE

  server: ver,1,0 ser,json,gob
  client: ver,1.0 ser,json

After a client has connected, the server sends the first 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. The client then replies with a similar message.

Currently defined parameters are:

=over

=item ver

Protocol version, 1 is the major version and 0 the minor. Minor versions are
used for backward-compatible additions to the protocol, whereas major version
changes indicate incompatibilities. If a server supports multiple major
versions, it can list these in the same ver parameter as, for example:
C<ver,1.5,2.3>. Since minor releases are always backward-compatible, only the
most recent supported version has to be listed.

The client replies with the version that will be used (e.g. C<ver,1.0>), most
likely with the highest version supported by both client and server.

=item ser

Serialization format. The server may indicate support for multiple
serialization formats, e.g. with C<ser,json,gob>. The client then decides which
format to use and indicates this in the reply (e.g. C<ser,json>).

=back



=head1 MESSAGES

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

=over

=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 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.

=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 responses to this tuple (at least, not through a response
channel), then $tid is 0. Any other value is a means to identify the return
channel for this tuple among other active return channels. This allows replies
to this tuple to be sent back with the RESPONSE 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 bound on when this CLOSE
has to occur)

It is not an error to receive a TUPLE message for a tuple that does not match
any of the patterns registered with REGISTER.

=item RESPONSE $tid $tuple

Send back a response tuple as reply to a TUPLE with the corresponding $tid.

=item CLOSE $tid

Close a response channel.

=back

Either side may close the connection at any point. It is not necessary for to
send CLOSE on open channels 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 RESPONSE

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 msgResponse struct {
    tid     int
    pattern Pattern
  }

  type msgClose struct {
    tid int
  }