This repository has been archived by the owner on Jan 23, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathgr-protocol.txt
1455 lines (1063 loc) · 39.6 KB
/
gr-protocol.txt
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
GRAPH REPOSITORY PROTOCOL
=========================
1. INTRO
This is the functional specification of the protocol used to
access the graph repository.
The protocol mainly alternates synchronous request from
client to server with synchronous replies from server to
client.
request:
read-request
/ write-request
/ dump-request
/ restore-request
/ cancel-request
/ set-request
/ status-request
/ replica-request
/ replica-write-request
/ sync-request
reply:
read-reply
/ write-reply
/ dump-reply
/ restore-reply
/ cancel-reply
/ error-reply
/ set-reply
/ status-reply
/ replica-reply
The server can also asynchronously notify a client about an
error that leads to it shutting down, but that's going to be
seen as an error response to the next command by the client.
(However, smart clients that are able to deal with incoming
asynchronous notifications from the server can notice that
early and recover from a server restart without causing a delay
visible to the user.)
1.1 Request Boundaries
Requests and responses are terminated by a newline outside
of a string literal or a parenthesized list.
1.1.1 Pipelining
Requests can be pipelined. Unless the application semantics
demand it, a request submitter does not have to wait to receive
a reply before submitting the next request. Nevertheless,
replies do arrive in the order of requests; to break up
requests with large responses, use paging.
1.1.2 Spanning transport boundaries
Requests can span message boundaries of the underlying
transport system. A request or reply can be larger than
what one "write" call to a TCP connection can dispose
of without blocking.
The system can impose a maximum request or response size.
2. ERRORS
Any request can result in an error on a couple of different levels.
The request may have been syntactically incorrect; the user may
have exceeded their allowance in storage time or space; the repository
may be shutting down; etc.
Errors are sent to the client in two parts: a machine-readable
code, and a more detailed human-readable error message filling in
details of the code.
error-reply:
"error" error-label reply-modifiers string
error-label:
"BADCURSOR"
/ "COST"
/ "DATELINE"
/ "EMPTY"
/ "EXISTS"
/ "NOTREPLICA"
/ "OUTDATED"
/ "READONLY"
/ "RESTORE"
/ "SEMANTICS"
/ "SHUTDOWN"
/ "SYNTAX"
/ "SYSTEM"
/ "TOOBIG"
/ "TOOMANY"
string: <double-quoted string>
Error labels and their meanings:
badcursor
the cursor parameter in a request
could not be decoded.
cost
the allowance specified in the cost=".."
parameter was exceeded by the request.
dateline
a dateline parameter includes an instance ID
that doesn't match that of the database.
empty
a request didn't match anything, or
referenced primitives that don't exist.
exists
a write request had "unique" constraints that
conflicted with existing primitives.
notreplica
an operation that only makes sense on a
replica server has been attempted on a non-replica server
readonly
access to the server has been set to
read-only.
restore
access to the server has been set to
restore-only. The client should retry its
request after a few seconds.
outdated
a write() is trying to version a GUID that
has already been versioned by another write().
shutdown
the system is being shut down;
reconnect after a little while.
The client should disconnect and try to
reconnect after a few seconds.
syntax
the request was syntactically wrong.
system
notify the server's system administrator.
toobig
a primitive the server tried to write was too big,
or one of the strings involved in the primitive
were too long to be encoded.
Currently, the primitive size limit is about 32k,
but details depend on the amount of compression for
one primitive.
Value strings up to 4k, and name strings up to 200
bytes, should never present a problem.
toomany
the number of matching primitives exceeded a
specified maximum count
3. REQUEST MODIFIERS
Certain parameters can be set on any request.
They're specified as an optional space-separated list after
the request's verb.
request-modifiers:
request-modifier request-modifiers
/ request-modifier
request-modifier:
"timeout" "=" seconds
/ "id" "=" atom
/ "dateline" "=" string
/ "asof" "=" ( string / guid / timestamp )
/ "cost" "=" string
/ "loglevel" "=" ( loglevel / "(" loglevels ")" )
loglevels: loglevel loglevels / ""
loglevel: "verbose" / "debug" / "detail"
/ "info" / "fail" / "overview" / "error" / "fatal"
/ "tile" / "query" / <other module-specific loglevels>
; "spew" is an alias for "verbose".
seconds:
+digits
Request modifiers and their meanings:
asof
Read-accesses happening in the course of this
request should be executed as if the database had
the indicated dateline.
The dateline can be specified in three ways:
- a string dateline, as returned by the dateline
request modifier, below.
- a GUID; the read-access is executed as of the
state just after the primitive had been added to the
system.
- a timestamp; the read access is executed as if
it were the time of that timestamp.
(In order for the last one to work, timestamps of primitives
added to the repository later must be greater than timestamps
of primitives added earlier.)
cost
Request that the cost of the request be reported,
and (optionally) place a limit on the amount of
work the request can take.
dateline
Request a dateline result, and demand an up-to-date
server reply.
The "dateline" is a compound "odometer reading" that
characterizes how up-to-date a server is. It is useful
in ensuring consistency between "read" and "write"
requests in a distributed system.
A client that writes can ask for a dateline to be
returned (by passing in dateline=""). It saves that
dateline, and then reuses it in a "read" request that
follows the "write". Even if the "read" request hits
a server other than the one that received the "write",
the dateline has enough information to allow the server
to judge whether it is "behind", and to cause it catch up
if needed.
id
The request can be cancelled by executing
a cancel request with the same id. Its response
will have the same "id=" modifier that was sent
in the request.
loglevel
While processing the request, increase the
server loglevel to the specified levels. The keywords
for the loglevels are the same as for the
server "log-level" configuration parameter.
timeout
If the request ends up taking longer than
<seconds>, the system makes a best effort
to return a timeout error and partial results.
3.1 Discussion
* User/Account/Security Identity could be another request modifier.
"Do this as X", with a view towards having different quota
and time constraints apply to different users.
(I don't think logging in as a person-user is worth it,
because application servers are going to multiplex sessions;
I'd rather do the hard authentication between application
server and client, and just authenticate the application server
as trusted. But that doesn't mean that different requests
can't have different quality of service.)
4. REPLY MODIFIERS
Certain parameters can be set on any reply.
They're specified as an optional comma-separated list after
the reply's data.
reply-modifiers:
reply-modifier
/ reply-modifier reply-modifiers
reply-modifier:
"redirect" "=" url
/ "timeout"
/ "id" "=" atom
/ "cost" "=" string
/ "dateline" "=" string
Reply modifiers and their meanings:
redirect
The server says: for this kind of query,
you should really connect to the other server
at "url"
dateline
The value of this modifier can be handed to a server
to request that it be at least this up-to-date before
attempting to fill a request.
timeout
The request timed out. The results may or
may not be partial.
id
The request that this is a reply to was tagged
with this id.
Currently, replies correspond synchronously
to requests. (They come back in the order the
requests were received.) If we ever introduce
an asynchronous modifier that allows replies
to overtake each other, this will be needed.
cost
The true cost of the request. The string contains
a space-separated list of name-value pairs.
tu time/user, number of milliseconds graphd spent
executing in user mode while computing the
answer to this request.
ts time/system, number of milliseconds graphd
spent executing in system mode while computing
the answer to this requests. "Executing in
system mode" almost always means "reading
a lot of data from disk".
tr time/real, number of milliseconds graphd spent
executing to answer this query in general. This
number will get larger on a system that is busy
with other things, even if graphd isn't involved
in them.
te time/end-to-end, number of milliseconds from
parsing the quest to formatting its result.
Unlike "tr", "te" includes time the request was
suspended while the server was working on completely
different requests. In an idle server, "tr" is
very close to "te". In a busy server, "tr" should
stay the same, and "te" should go up.
pr page reclaims, a benevolent form of page fault
that doesn't actually do any work because the
page is still in the local cache.
pf page faults, the thing we're trying to minimize.
Higher pf will usually be accompanied by a higher ts.
dw primitive data writes. Usually, these will be what
you expect, except for queries that create implicit
type links and type system fragments.
dr primitive data reads - how many single primitive
structs were read from disk (for example, as part
of dismissing them as candiates for a qualified
search).
in index size reads - how many indices were looked up
with their starting address and size.
ir index element reads - how many times a single id
was read from an index.
iw index element write - how many times an element
was added to an index.
va value allocations - how many times a (possibly
temporary or transient) result data structure
was allocated
ma memory allocations (in bytes) - how many bytes
are allocated at the end of the request
mm memory maximum (in bytes) - the largest number
of bytes allocated for the request at any one
time
mt memory total (in bytes) - all allocations added
up, disregarding calls to free or implied frees
through realloc.
fa fragment allocations - how many chunks of memory
are allocated at the end of the request. One
call to malloc() creates one fragment.
fm fragment maximum - how many chunks of memory
are allocated at most at any one time.
ft fragment total - how many calls were made to
allocate request-specific memory, disregarding
calls to free it up?
4.1 Discussion
* Maybe timeouts could be handled as a form of ad-hoc paging,
where the repository gets to invent a cursor and sorting
order. Then we can just handle it with the paging
requests. But it's hairy.
* Another request modifier could be the amount of storage
used by the request.
5. READ
read-request:
"read" [request-modifiers] template
For the template-grammar,see cvs:graph/doc/gr-template.txt
read-reply:
"ok" [reply-modifiers] list-tuple
The data returned by the list request is a list of lists and scalars.
The meaning of the list elements depends on the result= clause in
the template request; see cvs:graph/doc/gr-template.txt, section 14.1.
list-tuple:
"(" [tuples] ")"
tuples:
tuple tuples
/ tuple
tuple:
literal-part
6. WRITE
The write request is similar to the read request, with
certain restrictions and changes to the template.
write-request:
"write" [request-modifiers] literal-expression
GUIDs of new primitives are returned as a tuple.
write-reply:
"ok" [reply-modifiers] tuple
6.1 Write templates
The syntax used to write is a closely restricted subset of the
syntax used to read.
literal-expression:
"(" [ literal-parts ] ")"
Write templates do not have instructions associated with them.
literal-parts:
literal-parts literal-part
/ literal-part
literal-part:
meta-literal
/ guid-literal
/ timestamp-literal
/ valuetype-literal
/ string-literal
/ numeric-literal ; not yet implemented
/ primitive-literal
/ linkage-literal
/ live-literal
/ archival-literal
/ unique-literal
/ key-literal
/ comparator-literal
/ anchor-modifier
/ result-modifier
6.1.1 Meta Literal
Like meta-constraints (see gr-template.txt section 2), but
without "any".
meta-literal:
"->"
/ "<-"
/ "node"
The default meta literal is "node"; it is meaningless
and might as well be omitted.
6.1.2 Valuetype Literal
When writing, valuetypes and datatypes are completely synonymous.
("Datatype" is the old, symbolic notation; valuetype is the new,
numeric notation.)
Both accept small integers in the range 1..255 and the symbolic
datatype names null(1), string(2), integer(3), float(4), guid(5),
timestamp(6), url(7), bytestring(8), boolean(9).
(It is a good idea to switch to using the numbers, rather than the
symbolic names, but both work.)
valuetype-literal:
"valuetype" "=" valuetype
/ "datatype" "=" valuetype
valuetype: "string
/ "integer"
/ "float"
/ "timestamp"
/ "url"
/ "guid"
/ "bytestring"
/ "boolean"
/ "null"
/ <a small integer between 1 and 255.>
If neither a value nor a valuetype is specified, the valuetype defaults to
"null", or 1. If a value is specified in an insert request, but no valuetype,
the valuetype defaults to "string", or 2.
Other than that, value types do not influence the behavior of graphd with
respect to the values in any way. They are not evaluated when comparing
values or matching them. For all practical purposes, they are simply a
small integer that is stored in the primitive for arbitrary use by the
application.
6.1.3 GUID Literal
guid-literal:
"guid" "=" guid
/ "guid" "~=" guid
Written like a guid-constraint, i.e. "guid = 123.."
or "guid ~= 123.."
If a GUID constraint is present in a "write" request,
the newly written primitive is intended to version, that is,
to implicitly delete and take the place of, another primitive.
If the operator is =, the most recent version of the primitive
must be the one with the specified GUID. If the operator is
~=, the specified GUID may have been replaced by another primitive
in the mean time (and that one, in turn, by others); whatever the
most recent primitive in this lineage is is versioned.
(In other words, = is pessimistic, ~= is opportunistic,
about race conditions. If someone else has gotten in in the
meantime and versioned things, = fails, while ~= will just
quietly do the right thing. If the right thing happens to
be to go ahead with the write.)
If no GUID is specified, the system generates a new GUID.
The new GUID will not match any other existing GUID when
compared with ~= or =.
6.1.4 Timestamp Literal
Simlar to timestamp-constraints, but only real timestamps
are allowed as literals (not the "generational" operators
"newest" or "oldest"). The only possible operator is "=".
timestamp-literal:
"timestamp" "=" timestamp
timestamp:
y?yyyy ["-" mm ["-" dd ["T" hh [":" mm [":" ss ["." +n ]]]]]] ["Z"]
Unspecified parts of the timestamp are set to the minimum
allowed by the type. (I.e. 1 for months and days,
0 for hours, minutes, seconds.)
If no timestamp literal is supplied for a tuple, it
defaults to the current time.
The timezone is optional; if it is supplied, it must be "Z",
standing for UTC.
6.1.5 String Literal
Similar to string-constraints, but without matching.
The specified string is simply assigned.
string-literal:
literal
/ stringexpression "=" literal
stringexpression:
"type"
/ "name"
/ "value"
If there's no stringexpression= prefix, it defaults to "type=".
(In other words, (person) creates a new node of type person.)
If an "url" string literal is specified, the datatype is
implicitly forced to "url". It is an error to both have a
"url" string literal and a datatype other than "url".
6.1.6 Primitive Literal
Like primitive-constraints, primitive-literals recursively
specify groups of links or nodes that are implicitly
connected to their containing expression.
primitive-literal:
"(" "<-" linkage [literal-parts] ")"
/ [ linkage "->" ] "(" [literal-parts] ")"
linkage: "left"
/ "right"
/ "scope"
/ "typeguid"
The linkage-> or <-linkage specifies how the containing and the
contained primitive are connected. It can be omitted once if the
outer primitive is tagged with "->" or "<-" (which implies a
form of attachment between outer and inner primitive.)
6.1.7 Flag Literal
Flag literals concern flags set for the primitive.
There are two flags, "archival" and "live". Both are
"true" by default.
live-literal:
"live" "=" bool
archival-literal:
"archival" "=" bool
bool: "true" / "false"
By default, entries are considered archive-worthy.
By default, they're also intended as data additions to
the database state, not as markers for deleted records.
6.1.8 Linkage Literal
This is similar to 6.1.6 Primitive Literal, but only connects
the primitive to an existing other primitive with a given GUID,
without actually creating that primitive.
linkage-literal:
linkage "=" guid
/ linkage "~=" guid
It is an error to specify a left (source) guid for a "<-" link
that encloses a primitive or a "->" link that is not at the outermost
level. It is an error to specify a right (destination) guid for
a "<-" link that isn't at the toplevel, or for a "->" link that
contains other primitives.
6.1.9 Uniqueness Literal
The uniqueness literal places a restrictions on the write
expression that contains it. If the part of a write expression
that is tagged with a "unique=" modifier already exists at the
time the write request is executed, the write request fails.
unique-literal:
"unique" "=" "(" [unique-instruction-items] ")"
/ "unique" "=" unique-instruction-item
unique-instruction-items:
unique-instruction-item unique-instruction-items
/ unique-instruction-item
unique-instruction-item:
"name"
/ "typeguid"
/ "datatype"
/ "value"
/ "left"
/ "right"
/ "scope"
/ "timestamp"
Note that in spite of similar grammar to the "result" instruction,
uniqueness checks are limited to a smaller set of features.
The unique modifier has two effects: it turns on the existence-testing as
a precondition for the write to succeed; and it specifies what it means
for something to "already exist" - do the type and name have to match?
Type, name, and value? Just the value?
6.1.9.1 Use of unique to construct namespaces.
The normal use of unique is in the construction of namespaces.
Each namespace has a well-known headnode.
Unique labels are implemented as links between the named object
and the namespace headnode. When inserting the links, they are
inserted with a unique qualifier that includes the namespace and
the value; expressing that the value has to be unique within
the namespace.
6.1.9.2 Unique clustering
Uniqueness expressions can stretch across multiple primitives.
Any group of primitives that
(a) are connected to each other,
(b) are all tagged with "unique" in some way,
(c) and whose unique tags include the links between them
are one "unique cluster" that can independently match or fail.
6.1.9.2.1 Example: A cluster with two primitives
The command
write (name="Pat" unique=right right->(name="Kim" unique=name))
contains a single unique cluster, made up of the nodes tagged Pat and Kim.
Pat and Kim both have unique tags, and the link between them is part
of Pat's unique set.
6.1.9.2.2 Example: Separate clusters
If I swap Pat's "unique" feature set from "right" to "name"
write (name="Pat" unique=name right->(name="Kim" unique=name))
I get two clusters. Pat and Kim must both be unique, but
their connection - Pat's right - isn't part of Pat's unique set.
6.1.9.2.3 Effects of clustering on the outcome
Given the database created by
write (name="Pat")
write (name="Kim")
the write in example 6.1.9.2.1 succeeds, but the one in 6.1.9.2.2 fails.
The first write was matching a complete cluster of Pat->Kim; the second
write was matching Pat and Kim individually, and would then have connected
the results.
6.1.10 Key Literal
Key literals, used only in write requests, help roll a familiar sequence
of operations into one: a "read" to see if something is already there,
a versioning of the old or insertion of a new value with a "unique"
modifier, and a final "read" to get the new GUIDs of the destination.
key-literal:
"key" "=" "(" [key-instruction-items] ")"
/ "key" "=" key-instruction-item
key-instruction-items:
key-instruction-item key-instruction-items
/ key-instruction-item
key-instruction-item:
"name"
/ "typeguid"
/ "datatype"
/ "value"
/ "left"
/ "right"
/ "scope"
/ "timestamp"
The key literal designates those parts of a template that
identify a location in the graph (an "lvalue"); the remainder
of the template describes the state that the caller wants
that location to have, with the understanding that insertion,
versioning, and partial addition can be used to bring about
that state.
If there's no primitive that matches the "key" constraint,
the "write" call inserts the primitive, just as a write call
without key constraint would.
If the primitive exists with all the values just as described in
the "write" call, the call returns the GUID of the existing
primitive.
Finally, if the key fields match, but some of the rest don't,
the "write" call makes the minimal set of versioning changes and
additions needed to bring about the desired state, and returns
the set of GUIDs from the finished mix of old, versioned, and
new.
6.1.10.1 Key clusters
Key primitives cluster just like unique primitives. Each cluster
contains the largest possible connected group of primitives that
each have keys and are connected with links that are covered by
keys. If a read query built from the cluster parts matches,
the cluster matches, and will either version or just reuse
the primitive network. (Each member of the key cluster versions
its own corresponding member of the matched set, if needed.)
6.1.10.2 Pointed-to unkeyed expression clusters
If a keyed primitive points to an unkeyed primitive, and that
unkeyed primitive and those it points to already exist in the
requested form in the database, the unkeyed primitive is not
created over again if the pointing, keyed, primitive exists.
6.1.10.3 Keys and ~= don't mix
Because keys already imply versioning of a previous match, keys
cannot occur in graphd constraints that also contain ~= GUID
literals.
6.1.11 Comparator Literal
The comparator literal influences the way unique- or
key comparators compare values while checking for existence
of a value. Its syntax is exactly the same as the comparator
constraint syntax.
comparator-literal:
comparator-constraint
See gr-template.txt for details.
6.1.12 Anchor Modifier
anchor-modifier:
"anchor"
Any constraint or subtree labelled as an "anchor" must occur
exactly once in the database. If it does not exist, or if it
exists more than once, the call fails with error code EMPTY.
An explicitly tagged anchor implicitly includes any subconstraint
below it.
An explicitly or implicitly tagged anchor primitive also implicitly
taggs any other primitive it points to, but not those primitives'
subtrees (unless they are also tagged explicitly.)
For example, in
write (value="a"
(<-left value="b" anchor)
(<-left value="c")
(<-left value="d"))
the anchor-derived read query
read (value="a"
(<-left value="b"))
must match exactly one record. The GUIDs it returns are
connected to the newly written records (<- left value="c")
and (<-left value="d"). A total of two primitives are written
by the example write request.
6.1.13 Result Modifier
result-modifier:
"result" "=" result-pattern
result-pattern:
"(" result-patterns ")"
/ "guid"
/ "none"
/ "literal" "=" string
/ "contents"
result-patterns:
result-patterns result-pattern
/ ""
The result pattern possible in a "write" request is a smaller version
of that possible with a "read" request. Atomic patterns mean the
same they mean in a read context; unlike in read, the parentheses are
returned exactly as written, with no duplication or expansion.
The default result pattern for a write constraint is "(guid contents)".
7. CANCEL
cancel-request:
"cancel" request-modifiers
A "cancel" request is an announcement from the client that
it will not parse (i.e., throw away, skip) the results.
It gives a server that is in the middle of calculating a reply
leeway to stop calculating it and just send a perfunctory
"ok" or "error" response, and a server that is in the middle
of formatting the response to a reply leeway to stop formatting
it, close the string it is currently formatting (if any), and
terminate the reply with a single newline. The reply does
not have to be syntactically correct or a complete list.
* Not yet implemented.
8. CONNECTION ESTABLISHMENT
When a client connects to the server, there's a brief handshake
period in which they both agree on their respective identities,
transport layer protection, and protocol versions.
[Needs filling in.]
9. STATUS
A "status" request asks various modules in the graphd
interior for information about their status and operation.
This is intended as a testing and monitoring tool; the
operations should be fast enough to not significantly
affect server speed or functioning.
status-request:
"status" [request-modifiers] "(" status-request-items ")"
status-request-items:
status-request-item status-request-items
/ ''
status-request-item:
"access"
/ "connection" / "connection" / "conn"
/ "core"
/ "database" / "db"
/ "database-compression-id"
/ "database-insertion-id"
/ "diary"
/ "import"
/ "loglevel"
/ "memory" / "mem"
/ "replica" / "rep"
/ "sync"
/ "transactional"
/ "version"
status-reply:
"ok" [reply-modifiers] "(" status-reply-items ")"
status-reply-items:
status-reply-item status-reply-items
/ ''
The items in the connection reply occur in the order of the
corresponding keywords in the request.
status-reply-item:
status-access-reply
/ status-connection-reply
/ status-core-reply
/ status-database-reply
/ status-database-compression-id-reply
/ status-database-insertion-id-reply
/ status-diary-reply
/ status-import-reply
/ status-loglevel-reply
/ status-memory-reply
/ status-replica-reply
/ status-sync-reply
/ status-transactional-reply
/ status-version-reply
9.1 Connection Reply
The connection reply is a parenthesized list of per-connection
data, one for each connection (or "session") to the server.
status-connection_reply:
"(" status-connection-reply-items ")"
status-connection-reply-items:
status-connection-reply-item status-connection-reply-items
/ ""
status-connection-reply-item:
"("
<"> <ip-address> ":" <port> <"> ; the peer's IP address
<"> ("status" / "read" / "write" / "connect") <">
; the most recent action
<"> ("RUN" / "I/O" / "MEM") <">; what is it waiting for?
timestamp ; start time, in GMT
timestamp ; most recent action, in GMT
number ; bytes received
number ; bytes sent
number ; requests received
number ; requests sent
number ; milliseconds computed
string ; the full command
number ; session-id
number ; request-id
")"
9.2 Database Reply