moat-kv 0.71.0__py3-none-any.whl → 0.71.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- moat/kv/__init__.py +6 -7
- moat/kv/_cfg.yaml +3 -2
- moat/kv/actor/__init__.py +2 -1
- moat/kv/actor/deletor.py +4 -1
- moat/kv/auth/__init__.py +12 -13
- moat/kv/auth/_test.py +4 -1
- moat/kv/auth/password.py +11 -7
- moat/kv/backend/mqtt.py +4 -5
- moat/kv/client.py +20 -39
- moat/kv/code.py +3 -3
- moat/kv/command/data.py +4 -3
- moat/kv/command/dump/__init__.py +36 -34
- moat/kv/command/internal.py +2 -3
- moat/kv/command/job.py +1 -2
- moat/kv/command/type.py +3 -6
- moat/kv/data.py +9 -8
- moat/kv/errors.py +16 -8
- moat/kv/mock/__init__.py +2 -12
- moat/kv/model.py +29 -33
- moat/kv/obj/__init__.py +3 -3
- moat/kv/obj/command.py +3 -3
- moat/kv/runner.py +4 -5
- moat/kv/server.py +106 -126
- moat/kv/types.py +10 -12
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/METADATA +6 -2
- moat_kv-0.71.7.dist-info/RECORD +47 -0
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/WHEEL +1 -1
- moat_kv-0.71.7.dist-info/licenses/LICENSE +3 -0
- moat_kv-0.71.7.dist-info/licenses/LICENSE.APACHE2 +202 -0
- moat_kv-0.71.7.dist-info/licenses/LICENSE.MIT +20 -0
- moat_kv-0.71.7.dist-info/top_level.txt +1 -0
- build/lib/docs/source/conf.py +0 -201
- build/lib/examples/pathify.py +0 -45
- build/lib/moat/kv/__init__.py +0 -19
- build/lib/moat/kv/_cfg.yaml +0 -93
- build/lib/moat/kv/_main.py +0 -91
- build/lib/moat/kv/actor/__init__.py +0 -98
- build/lib/moat/kv/actor/deletor.py +0 -139
- build/lib/moat/kv/auth/__init__.py +0 -444
- build/lib/moat/kv/auth/_test.py +0 -166
- build/lib/moat/kv/auth/password.py +0 -234
- build/lib/moat/kv/auth/root.py +0 -58
- build/lib/moat/kv/backend/__init__.py +0 -67
- build/lib/moat/kv/backend/mqtt.py +0 -71
- build/lib/moat/kv/client.py +0 -1025
- build/lib/moat/kv/code.py +0 -236
- build/lib/moat/kv/codec.py +0 -11
- build/lib/moat/kv/command/__init__.py +0 -1
- build/lib/moat/kv/command/acl.py +0 -180
- build/lib/moat/kv/command/auth.py +0 -261
- build/lib/moat/kv/command/code.py +0 -293
- build/lib/moat/kv/command/codec.py +0 -186
- build/lib/moat/kv/command/data.py +0 -265
- build/lib/moat/kv/command/dump/__init__.py +0 -143
- build/lib/moat/kv/command/error.py +0 -149
- build/lib/moat/kv/command/internal.py +0 -248
- build/lib/moat/kv/command/job.py +0 -433
- build/lib/moat/kv/command/log.py +0 -53
- build/lib/moat/kv/command/server.py +0 -114
- build/lib/moat/kv/command/type.py +0 -201
- build/lib/moat/kv/config.py +0 -46
- build/lib/moat/kv/data.py +0 -216
- build/lib/moat/kv/errors.py +0 -561
- build/lib/moat/kv/exceptions.py +0 -126
- build/lib/moat/kv/mock/__init__.py +0 -101
- build/lib/moat/kv/mock/mqtt.py +0 -159
- build/lib/moat/kv/mock/tracer.py +0 -63
- build/lib/moat/kv/model.py +0 -1069
- build/lib/moat/kv/obj/__init__.py +0 -646
- build/lib/moat/kv/obj/command.py +0 -241
- build/lib/moat/kv/runner.py +0 -1347
- build/lib/moat/kv/server.py +0 -2809
- build/lib/moat/kv/types.py +0 -513
- ci/rtd-requirements.txt +0 -4
- ci/test-requirements.txt +0 -7
- ci/travis.sh +0 -96
- debian/.gitignore +0 -7
- debian/changelog +0 -1435
- debian/control +0 -43
- debian/moat-kv/usr/lib/python3/dist-packages/docs/source/conf.py +0 -201
- debian/moat-kv/usr/lib/python3/dist-packages/examples/pathify.py +0 -45
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/__init__.py +0 -19
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml +0 -93
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_main.py +0 -91
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/__init__.py +0 -98
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/deletor.py +0 -139
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/__init__.py +0 -444
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/_test.py +0 -166
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/password.py +0 -234
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/root.py +0 -58
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/__init__.py +0 -67
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py +0 -71
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/client.py +0 -1025
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/code.py +0 -236
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/codec.py +0 -11
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/__init__.py +0 -1
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/acl.py +0 -180
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/auth.py +0 -261
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/code.py +0 -293
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/codec.py +0 -186
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/data.py +0 -265
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/dump/__init__.py +0 -143
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/error.py +0 -149
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/internal.py +0 -248
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/job.py +0 -433
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/log.py +0 -53
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/server.py +0 -114
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/type.py +0 -201
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/config.py +0 -46
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/data.py +0 -216
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/errors.py +0 -561
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/exceptions.py +0 -126
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/__init__.py +0 -101
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/mqtt.py +0 -159
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/tracer.py +0 -63
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/model.py +0 -1069
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/__init__.py +0 -646
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/command.py +0 -241
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/runner.py +0 -1347
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/server.py +0 -2809
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/types.py +0 -513
- debian/moat-kv.postinst +0 -3
- debian/rules +0 -20
- debian/source/format +0 -1
- debian/watch +0 -4
- docs/Makefile +0 -20
- docs/make.bat +0 -36
- docs/source/TODO.rst +0 -61
- docs/source/_static/.gitkeep +0 -0
- docs/source/acls.rst +0 -80
- docs/source/auth.rst +0 -84
- docs/source/client_protocol.rst +0 -456
- docs/source/code.rst +0 -341
- docs/source/command_line.rst +0 -1187
- docs/source/common_protocol.rst +0 -47
- docs/source/conf.py +0 -201
- docs/source/debugging.rst +0 -70
- docs/source/extend.rst +0 -37
- docs/source/history.rst +0 -36
- docs/source/index.rst +0 -75
- docs/source/model.rst +0 -54
- docs/source/overview.rst +0 -83
- docs/source/related.rst +0 -89
- docs/source/server_protocol.rst +0 -450
- docs/source/startup.rst +0 -31
- docs/source/translator.rst +0 -244
- docs/source/tutorial.rst +0 -711
- docs/source/v3.rst +0 -168
- examples/code/transform.scale.yml +0 -21
- examples/code/transform.switch.yml +0 -82
- examples/code/transform.timeslot.yml +0 -63
- examples/pathify.py +0 -45
- moat/kv/codec.py +0 -11
- moat_kv-0.71.0.dist-info/RECORD +0 -188
- moat_kv-0.71.0.dist-info/top_level.txt +0 -9
- scripts/current +0 -15
- scripts/env +0 -8
- scripts/init +0 -39
- scripts/recover +0 -17
- scripts/rotate +0 -33
- scripts/run +0 -29
- scripts/run-all +0 -10
- scripts/run-any +0 -10
- scripts/run-single +0 -15
- scripts/success +0 -4
- systemd/moat-kv-recover.service +0 -21
- systemd/moat-kv-rotate.service +0 -20
- systemd/moat-kv-rotate.timer +0 -10
- systemd/moat-kv-run-all.service +0 -26
- systemd/moat-kv-run-all@.service +0 -25
- systemd/moat-kv-run-any.service +0 -26
- systemd/moat-kv-run-any@.service +0 -25
- systemd/moat-kv-run-single.service +0 -26
- systemd/moat-kv-run-single@.service +0 -25
- systemd/moat-kv.service +0 -27
- systemd/postinst +0 -7
- systemd/sysusers +0 -3
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/licenses/LICENSE.txt +0 -0
docs/source/server_protocol.rst
DELETED
@@ -1,450 +0,0 @@
|
|
1
|
-
========================
|
2
|
-
MoaT-KV's server protocol
|
3
|
-
========================
|
4
|
-
|
5
|
-
MoaT-KV instances broadcast messages via `MQTT <https://mqtt.org>`.
|
6
|
-
The payload is encoded with `msgpack
|
7
|
-
<https://github.com/msgpack/msgpack/blob/master/spec.md>` and sent
|
8
|
-
to topics (MQTT) with a configurable prefix.
|
9
|
-
|
10
|
-
|
11
|
-
++++++++++
|
12
|
-
Data types
|
13
|
-
++++++++++
|
14
|
-
|
15
|
-
Node
|
16
|
-
++++
|
17
|
-
|
18
|
-
A node represents a server that has injected at least one data item into
|
19
|
-
the DiskKV network. Each node has an associated "tick", which is the
|
20
|
-
sequence number of the last change that this node injected into the
|
21
|
-
network. An empty node starts with a counter of zero; the network's first
|
22
|
-
node starts with 1.
|
23
|
-
|
24
|
-
Entry
|
25
|
-
+++++
|
26
|
-
|
27
|
-
An entry is some data stored in MoaT-KV. The entry has a name, or (more
|
28
|
-
correctly) a path, i.e. a sequence of names leading from the server's root
|
29
|
-
to the entry. An entry can store one chunk of data, or it can be empty.
|
30
|
-
|
31
|
-
Path members may be UTF-8 strings, byte strings, or numbers. The empty
|
32
|
-
UTF-8 and byte strings are considered equivalent, any other values are not.
|
33
|
-
If you want to use the MoaT-KV command line to access data, you should limit
|
34
|
-
yourself to UTF-8 strings.
|
35
|
-
|
36
|
-
For ensuring consistency, each entry also has an associated chain, which
|
37
|
-
documents which node(s) last changed that entry.
|
38
|
-
|
39
|
-
Chain
|
40
|
-
+++++
|
41
|
-
|
42
|
-
A chain, in MoaT-KV, is a bounded list of ordered ``(node, tick)`` pairs.
|
43
|
-
|
44
|
-
* ``node`` is the node that effected a change.
|
45
|
-
|
46
|
-
* ``tick`` is a node-specific counter which increments by one when any
|
47
|
-
entry on that node is changed.
|
48
|
-
|
49
|
-
A chain entry might not have a ``tick`` element. In that case the node has
|
50
|
-
not been initialized yet. Such entries are only valid in ``ping`` chains.
|
51
|
-
|
52
|
-
Chains are governed by three rules:
|
53
|
-
|
54
|
-
* The most recent change is at the front of the chain.
|
55
|
-
|
56
|
-
* Any node may only appear on the chain once, with the ``tick`` of the
|
57
|
-
latest change by that node. If a node changes an entry again, the old
|
58
|
-
entry is removed before the new entry is prepended.
|
59
|
-
|
60
|
-
This rule does not apply to ``ping`` chains.
|
61
|
-
|
62
|
-
* Their length is bounded. If a new entry causes the chain to grow too
|
63
|
-
long, the oldest entry is removed.
|
64
|
-
|
65
|
-
Chains are typically represented by ``(node,tick,prev)`` maps, where
|
66
|
-
``prev`` is either ``None`` (the chain ends here), nonexistent (the chain
|
67
|
-
was truncated here), or another chain triple (the last previous change on a
|
68
|
-
different node).
|
69
|
-
|
70
|
-
Ticks increment sequentially so that every node can verify that it
|
71
|
-
knows all of every other node's changes.
|
72
|
-
|
73
|
-
The chain concept is based on `vector clocks <https://queue.acm.org/detail.cfm?id=2917756>`.
|
74
|
-
Nodes are sorted so that causality may be established more easily (no need
|
75
|
-
to compare the whole vectors) and vector length may be bounded without
|
76
|
-
sacrificing reliability.
|
77
|
-
|
78
|
-
The default chain length should be two larger than the maximum of
|
79
|
-
|
80
|
-
* the number of partitions a MoaT-KV system might break up into,
|
81
|
-
|
82
|
-
* the number of hosts within one partition that might change any single entry.
|
83
|
-
Ideally, this number should be two: one for the host that does it as a
|
84
|
-
matter of fact, e.g. a measurement system, and one for any manual intercession.
|
85
|
-
|
86
|
-
tick
|
87
|
-
++++
|
88
|
-
|
89
|
-
Each node has an associated tick, which is a contiguous counter of changes
|
90
|
-
by that node. Each value between one and a node's ``tick`` must be
|
91
|
-
present either in exactly one entry's chain or in that node's ``known``
|
92
|
-
range.
|
93
|
-
|
94
|
-
Tick values are 63-bit unsigned integers. As this space requires 20 mio
|
95
|
-
years to wrap around, assuming ten messages per millisecond, the MoaT-KV
|
96
|
-
protocol does not specify what shall happen if this value overflows.
|
97
|
-
|
98
|
-
tock
|
99
|
-
++++
|
100
|
-
|
101
|
-
The ``tock`` counter is a system-wide number that's incremented whenever
|
102
|
-
something interesting happens on a node (most important: some entry is
|
103
|
-
changed). All messages carry the current ``tock`` value; entries store the
|
104
|
-
``tock`` from their last change. Whenever a MoaT-KV server receives a
|
105
|
-
message with a ``tock`` higher than its own, the local ``tock`` is set to
|
106
|
-
the incoming message's ``tock`` value.
|
107
|
-
|
108
|
-
The main purpose of this value is to establish rough temporal consistency
|
109
|
-
(in the absence of network splits). Secondarily, when a split is healed,
|
110
|
-
their ``tock`` value resolves the resulting Actor conflict. (The tie
|
111
|
-
breaker is the name of the current group leaders.)
|
112
|
-
|
113
|
-
Coordination
|
114
|
-
++++++++++++
|
115
|
-
|
116
|
-
Nodes coordinate so that any housekeeping messages are transmitted by
|
117
|
-
exactly one node instead of flooding the network. This is facilitated by
|
118
|
-
the ``asyncactor`` module.
|
119
|
-
|
120
|
-
When a network split is healed, the Actor protocol notices. It then
|
121
|
-
triggers ``info`` messages that retrieve any missed changes.
|
122
|
-
|
123
|
-
Putting it all together
|
124
|
-
+++++++++++++++++++++++
|
125
|
-
|
126
|
-
Each node has a tick counter that increments when you change anything; it's
|
127
|
-
also broadcast periodically. Thus, each node notices when there's missing
|
128
|
-
data and will send a message seeking the missing items.
|
129
|
-
|
130
|
-
Each node is associated with a range of ``known`` ticks, which says "yes I
|
131
|
-
have once seen this message, but it's been superseded".
|
132
|
-
|
133
|
-
The entries' ``chain`` data ensures that stale data cannot overwrite more
|
134
|
-
recent messages.
|
135
|
-
|
136
|
-
Deletion of entries
|
137
|
-
+++++++++++++++++++
|
138
|
-
|
139
|
-
The entries' change chains determine that no entry gets lost, but that
|
140
|
-
mechanism depends on the entries themselves to exist. In a MoaT-KV system
|
141
|
-
that's highly dynamic, this is undesireable and would cause a lot of stale
|
142
|
-
entries to accumulate. Removing these entries must be coordinated: if a
|
143
|
-
removal is lost for any reason, the system cannot recover without manual
|
144
|
-
intervention.
|
145
|
-
|
146
|
-
Therefore, each node also carries a ``deleted`` list which marks entries
|
147
|
-
that have been cleared. Deleted entries will only be cleared if all nodes
|
148
|
-
that are on the internal "deleter" list are online.
|
149
|
-
|
150
|
-
|
151
|
-
++++++++++++
|
152
|
-
Common items
|
153
|
-
++++++++++++
|
154
|
-
|
155
|
-
Bidirectional
|
156
|
-
+++++++++++++
|
157
|
-
|
158
|
-
path
|
159
|
-
----
|
160
|
-
|
161
|
-
The path to the entry you're accessing. This is a list. The contents of
|
162
|
-
that list may be anything hashable, i.e. strings, integers,
|
163
|
-
``True``/``False``/``None``.
|
164
|
-
|
165
|
-
.. note:
|
166
|
-
|
167
|
-
``None`` is MoaT-KV's special name for its meta hierarchy, i.e. data
|
168
|
-
about itself (user IDs, file conversion code, …). As such it is not
|
169
|
-
directly accessible.
|
170
|
-
|
171
|
-
value
|
172
|
-
-----
|
173
|
-
|
174
|
-
A node's value. This can be anything that ``msgpack`` can work with: you do
|
175
|
-
not need to encode your values to binary strings, and in fact you should
|
176
|
-
not because some of MoaT-KV's features (like type checking) would no longer
|
177
|
-
work, or be much more awkward to use.
|
178
|
-
|
179
|
-
Replies
|
180
|
-
+++++++
|
181
|
-
|
182
|
-
node
|
183
|
-
----
|
184
|
-
|
185
|
-
The node which is responsible for this message. For ``update`` events this
|
186
|
-
is the node which originated the change; for all other events, it's the
|
187
|
-
sending node.
|
188
|
-
|
189
|
-
tick
|
190
|
-
----
|
191
|
-
|
192
|
-
This node's current tick. The tick is incremented every time a value is changed by that node.
|
193
|
-
|
194
|
-
prev
|
195
|
-
----
|
196
|
-
|
197
|
-
A dict with ``node,tick,prev`` entries, which describes the node which
|
198
|
-
originated the change that is is based on.
|
199
|
-
|
200
|
-
If this value is ``None``, the entry has been created at that time. If it
|
201
|
-
is missing, further chain members have been elided.
|
202
|
-
|
203
|
-
In the client protocol, the ``node``, ``tick`` and ``prev`` members are
|
204
|
-
stored in a ``chain`` element; otherwise the semantics are the same.
|
205
|
-
|
206
|
-
A chain will not contain any node more than once. When a value is changed
|
207
|
-
again, that node's ``tick`` is incremented, its entry is added or moved
|
208
|
-
to the head of the chain.
|
209
|
-
|
210
|
-
tock
|
211
|
-
----
|
212
|
-
|
213
|
-
This is a global message counter. Each server has one; it is incremented
|
214
|
-
every time its node counter is incremented or a MQTT message is sent.
|
215
|
-
A server must not send a message with a smaller (or equal) ``tock`` value
|
216
|
-
than any it has received, or previously sent. Since MQTT does ot guarantee
|
217
|
-
order of delivery, receiving a message with a smaller ``tock`` than the
|
218
|
-
preceding one is not an error.
|
219
|
-
|
220
|
-
+++++++++++++
|
221
|
-
Message types
|
222
|
-
+++++++++++++
|
223
|
-
|
224
|
-
update
|
225
|
-
++++++
|
226
|
-
|
227
|
-
This message updates an entry.
|
228
|
-
|
229
|
-
Each server remembers the change chain's per-node ``tick`` values so that
|
230
|
-
it can verify that all messages from other servers have been received.
|
231
|
-
|
232
|
-
path
|
233
|
-
----
|
234
|
-
|
235
|
-
The list of path elements leading to the entry to be updated.
|
236
|
-
|
237
|
-
value
|
238
|
-
-----
|
239
|
-
|
240
|
-
The value to set. ``Null`` means the same as deleting the entry.
|
241
|
-
|
242
|
-
info
|
243
|
-
++++
|
244
|
-
|
245
|
-
This message contains generic information. It is sent whenever required.
|
246
|
-
|
247
|
-
known
|
248
|
-
-----
|
249
|
-
|
250
|
-
This element contains a map of (node ⇒ ranges of tick values) which the
|
251
|
-
sending server has seen. This includes existing events as well as events
|
252
|
-
that no longer exist; this happens when a node re-updates an entry.
|
253
|
-
|
254
|
-
This message's change chain refers to the ``ping`` it replies to.
|
255
|
-
|
256
|
-
ticks
|
257
|
-
-----
|
258
|
-
|
259
|
-
This element contains a map of (node ⇒ last_tick_seen), sent to verify that
|
260
|
-
|
261
|
-
missing
|
262
|
-
-------
|
263
|
-
|
264
|
-
A map of (node ⇒ ranges of tick values) which the sending node has not
|
265
|
-
seen. Any node that sees this request will re-send change messages in that
|
266
|
-
range.
|
267
|
-
|
268
|
-
reason
|
269
|
-
------
|
270
|
-
|
271
|
-
This element is sent in the first step of split reconciliation recovery. If
|
272
|
-
the first ``ping`` after being reconnected "wins", then the winning side
|
273
|
-
needs to be told that there's a problem.
|
274
|
-
|
275
|
-
This element contains the losing side's ping chain, which the nodes in the
|
276
|
-
winning side's ping chain use to initiate their recovery procedure.
|
277
|
-
|
278
|
-
ping
|
279
|
-
++++
|
280
|
-
|
281
|
-
A periodic "I am alive" message. This message's change chain shows which
|
282
|
-
node was pinged previously.
|
283
|
-
|
284
|
-
++++++++++++++++++++++
|
285
|
-
Timing and concurrency
|
286
|
-
++++++++++++++++++++++
|
287
|
-
|
288
|
-
Server to Server
|
289
|
-
++++++++++++++++
|
290
|
-
|
291
|
-
Ping sequence
|
292
|
-
-------------
|
293
|
-
|
294
|
-
Every ``clock`` seconds each node starts thinking about sending a ``ping``
|
295
|
-
sometime during the next ``clock`` seconds. The node that's last in the
|
296
|
-
chain (assuming that the chain has maximum length) does this quite early,
|
297
|
-
while the node that transmitted the previous ``ping`` does this at the end
|
298
|
-
of the interval. Nodes not in the current chain do this immediately, with
|
299
|
-
some low probability (one to 10 times the number of known nodes) so that
|
300
|
-
the chain varies. If no ``ping`` has arrived after another ``clock/2``
|
301
|
-
seconds, each node sends a ping sometime during the next ``clock/2``
|
302
|
-
seconds. Thus, at least one ``ping`` must be seen every ``3*clock``
|
303
|
-
seconds.
|
304
|
-
|
305
|
-
Ping messages can collide. If so, the message with the higher ``tock``
|
306
|
-
value wins. If they match, the node with the higher ``tick`` value wins. If
|
307
|
-
they match too, the node with the alphabetically-lower name wins. The
|
308
|
-
winning message becomes the basis for the next cycle.
|
309
|
-
|
310
|
-
This protocol assumes that the ``prev`` chains of any colliding ticks are
|
311
|
-
identical. If they are not, there was at least one network split that is
|
312
|
-
now healed. When this is detected, the nodes mentioned in the messages'
|
313
|
-
chains send ``info`` messages containing ``ticks`` for all nodes they know.
|
314
|
-
The non-topmost nodes will delay this message by ``clock/ping.length``
|
315
|
-
(times their position in the chain) seconds and not send their message if
|
316
|
-
they see a previous node's message first. Resolution of which chain is the
|
317
|
-
"real" one shall proceed as above.
|
318
|
-
|
319
|
-
``clock`` is configurable (``ping.clock``); the default is ``5``. It must be at
|
320
|
-
least twice the time MQTT requires to delivers a message to all nodes.
|
321
|
-
|
322
|
-
The length of the ping chain is likewise configurable (``ping.length``).
|
323
|
-
It should be larger than the number of possible network partitions; the
|
324
|
-
default is 4.
|
325
|
-
|
326
|
-
|
327
|
-
Startup
|
328
|
-
-------
|
329
|
-
|
330
|
-
When starting up, a new node sends a ``ping`` query with an empty ``prev``
|
331
|
-
chain, every ``3*clock`` seconds. The initial ``tick`` value shall be zero;
|
332
|
-
the first message shall be delayed by a random interval between ``clock/2``
|
333
|
-
and ``clock`` seconds.
|
334
|
-
|
335
|
-
Reception of an initial ``ping`` does trigger an ``info`` message, but does not
|
336
|
-
affect the regular ``ping`` interval, on nodes that already participate in
|
337
|
-
the protocol. A new node, however, may assume that the ``ping`` message it
|
338
|
-
sees is authoritative (unless the "new" ``ping`` is followed by one with a
|
339
|
-
non-empty chain). In case of multiple nodes joining a new network, the last
|
340
|
-
``ping`` seen shall be the next entry in the chain.
|
341
|
-
|
342
|
-
The new node is required to contact a node in the (non-empty) ping chain it
|
343
|
-
attaches to, in order to download its current set of entries, before
|
344
|
-
answering client queries. If a new node does already know a (possibly
|
345
|
-
outdated) set of messages and there is no authoritative chain, it shall
|
346
|
-
broadcast them in a series of ``update`` messages.
|
347
|
-
|
348
|
-
The first node that initiates a new network shall send an ``update`` event
|
349
|
-
for the root node (with any value). A chain is not authoritative if it only
|
350
|
-
contains nodes with zero ``tick`` values. Nodes with zero ticks shall not
|
351
|
-
send a ``ping`` when the first half of the chain does not contain a
|
352
|
-
non-zero-tick node (unless the second half doesn't contain any such nodes
|
353
|
-
either).
|
354
|
-
|
355
|
-
The practical effect of this is that when a network is restarted,
|
356
|
-
fast-starting empty nodes will quickly agree on a ``ping`` sequence. A node
|
357
|
-
with recovered data, which presumably takes longer to start up since it has
|
358
|
-
to load the data first, will then take over as soon as it is operational;
|
359
|
-
it will not be booted from the chain by nodes that don't yet have recovered
|
360
|
-
the data store.
|
361
|
-
|
362
|
-
|
363
|
-
Event recovery
|
364
|
-
--------------
|
365
|
-
|
366
|
-
After a network split is healed, there can be any number of update events
|
367
|
-
that the "other side" doesn't know about. These need to be redistributed.
|
368
|
-
|
369
|
-
Step zero: a ``ping`` message with an incompatible chain arrives.
|
370
|
-
|
371
|
-
First step: Send an ``info`` message with a ``ticks`` element, so that any
|
372
|
-
node that has been restarted knows which tick value they are supposed to
|
373
|
-
continue with.
|
374
|
-
|
375
|
-
Second step (after half a tick): Send a message with ``missing`` elements
|
376
|
-
that describe which events you do not yet know about.
|
377
|
-
|
378
|
-
Third step: Nodes retransmit missing events, followed by a ``known``
|
379
|
-
message that lists ticks which no longer appear on an event's chain.
|
380
|
-
|
381
|
-
After completing this sequence, every node should have a node list which
|
382
|
-
marks no event as missing. For error recovery, a node may randomly
|
383
|
-
(at most one such request every ``10*clock`` interval) retransmit its
|
384
|
-
local ``missing`` list, assuming there is one.
|
385
|
-
|
386
|
-
This protocol assumes that new nodes connect to an existing non-split
|
387
|
-
network. If new nodes first form their own little club before being
|
388
|
-
reconnected to the "real" network (or a branch of it), this would force a
|
389
|
-
long list of events to be retransmitted. Therefore, nodes with zero ticks
|
390
|
-
must initially be passive. They shall open a client connection to any
|
391
|
-
on-chain node and download its state. If a node has received a non-zero
|
392
|
-
tick for itself in a ``known`` message, it may participate only after it
|
393
|
-
has received a complete download, and must not allow client connections
|
394
|
-
before its list of missing events is empty.
|
395
|
-
|
396
|
-
All of these steps are to be performed by the first nodes in the pre-joined
|
397
|
-
chains. If these messages are not seen after ``clock/2`` seconds (counting
|
398
|
-
from reception of the ``ping``, ``ticks`` or ``missing`` element that
|
399
|
-
occured in the previous step), the second node in the chain is required to
|
400
|
-
send them; the third node will take over after an additional ``clock/4``
|
401
|
-
interval, and so on. Of course, only messages originating from hosts on the
|
402
|
-
correct chain shall suppress a node's transmission.
|
403
|
-
|
404
|
-
++++++++++++++
|
405
|
-
Message graphs
|
406
|
-
++++++++++++++
|
407
|
-
|
408
|
-
Yes, I need to visualize (and test) all of this.
|
409
|
-
|
410
|
-
TODO.
|
411
|
-
|
412
|
-
++++++++++++++++
|
413
|
-
MsgPack encoding
|
414
|
-
++++++++++++++++
|
415
|
-
|
416
|
-
MoaT-KV encodes its messages with MsgPack. It's fast, compact,
|
417
|
-
self-delimiting, and easily translated from/to human-readable YAML.
|
418
|
-
|
419
|
-
MoaT-KV uses the following MsgPack extensions:
|
420
|
-
|
421
|
-
2: big unsigned integer
|
422
|
-
+++++++++++++++++++++++
|
423
|
-
|
424
|
-
MsgPack is limited to 64bit integers. We exceed that: IPv6 network
|
425
|
-
addresses are longer. Thus, longer unsigned integers are stored in this
|
426
|
-
extension. Storage is big-endian and required to be minimal, i.e. the first
|
427
|
-
byte must not be zero. The length must be >8 obviously.
|
428
|
-
|
429
|
-
3: Path
|
430
|
-
+++++++
|
431
|
-
|
432
|
-
Distinguishing Path from ``list`` / ``tuple`` makes sense, if only to clean
|
433
|
-
up YAML output. Thus, paths are stored separately. The extension's content
|
434
|
-
is the sequence of encoded path elements.
|
435
|
-
|
436
|
-
+++++++++++++
|
437
|
-
YAML encoding
|
438
|
-
+++++++++++++
|
439
|
-
|
440
|
-
MoaT-KV uses clean, "safe" YAML with no frills, resulting in a simple
|
441
|
-
human-readable data format.
|
442
|
-
|
443
|
-
MoaT-KV's YAML supports two extensions: ``!P`` and ``!bin``.
|
444
|
-
|
445
|
-
``!P`` marks a `Path`, which makes the resulting YAML more compact and
|
446
|
-
readable.
|
447
|
-
|
448
|
-
``!bin`` encodes binary data as ASCII, i.e. a simple YAML string. YAML's
|
449
|
-
default is ``base64`` which cannot be easily edited.
|
450
|
-
|
docs/source/startup.rst
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
Starting MoaT-KV
|
2
|
-
================
|
3
|
-
|
4
|
-
MoaT-KV is generally started by a systemd service.
|
5
|
-
|
6
|
-
You can start a MoaT-KV service in one of three ways:
|
7
|
-
|
8
|
-
* Slave, i.e. no persistent storage.
|
9
|
-
|
10
|
-
* Master, i.e. always starts with persistent storage.
|
11
|
-
|
12
|
-
* Hybrid, i.e. tries to start from the network but loads persistent data
|
13
|
-
when that fails.
|
14
|
-
|
15
|
-
Slave mode is used when ``/var/lib/moat/kv`` does not exist.
|
16
|
-
|
17
|
-
Master mode is used when ``MODE=master`` is set in ``/etc/moat/kv.env``.
|
18
|
-
|
19
|
-
Hybrid mode is used when neither of the above is true.
|
20
|
-
|
21
|
-
Master and hybrid mode use a systemd timer unit to rotate the logs.
|
22
|
-
The rotation period is specified in the ``moat-kv.timer`` unit; it can be
|
23
|
-
overridden via systemd as usual.
|
24
|
-
|
25
|
-
The period for starting a new log is specified by the DATE format variable
|
26
|
-
in ``/etc/moat/kv.env``; the default is "daily", i.e. ``%Y-%m-%d``. If you
|
27
|
-
change this format, you must only use strictly incrementing values: month
|
28
|
-
numbers and Y-M-D format is OK but M-D-Y or month/day names is not. See
|
29
|
-
``man date`` for details. You may use slashes in the format to subdivide
|
30
|
-
the files further.
|
31
|
-
|