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