moat-kv 0.70.22__py3-none-any.whl → 0.70.24__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.
- build/lib/docs/source/conf.py +201 -0
- build/lib/examples/pathify.py +45 -0
- build/lib/moat/kv/__init__.py +19 -0
- build/lib/moat/kv/_cfg.yaml +97 -0
- build/lib/moat/kv/_main.py +91 -0
- build/lib/moat/kv/actor/__init__.py +98 -0
- build/lib/moat/kv/actor/deletor.py +139 -0
- build/lib/moat/kv/auth/__init__.py +444 -0
- build/lib/moat/kv/auth/_test.py +166 -0
- build/lib/moat/kv/auth/password.py +234 -0
- build/lib/moat/kv/auth/root.py +58 -0
- build/lib/moat/kv/backend/__init__.py +67 -0
- build/lib/moat/kv/backend/mqtt.py +74 -0
- build/lib/moat/kv/backend/serf.py +45 -0
- build/lib/moat/kv/client.py +1025 -0
- build/lib/moat/kv/code.py +236 -0
- build/lib/moat/kv/codec.py +11 -0
- build/lib/moat/kv/command/__init__.py +1 -0
- build/lib/moat/kv/command/acl.py +180 -0
- build/lib/moat/kv/command/auth.py +261 -0
- build/lib/moat/kv/command/code.py +293 -0
- build/lib/moat/kv/command/codec.py +186 -0
- build/lib/moat/kv/command/data.py +265 -0
- build/lib/moat/kv/command/dump/__init__.py +143 -0
- build/lib/moat/kv/command/error.py +149 -0
- build/lib/moat/kv/command/internal.py +248 -0
- build/lib/moat/kv/command/job.py +433 -0
- build/lib/moat/kv/command/log.py +53 -0
- build/lib/moat/kv/command/server.py +114 -0
- build/lib/moat/kv/command/type.py +201 -0
- build/lib/moat/kv/config.py +46 -0
- build/lib/moat/kv/data.py +216 -0
- build/lib/moat/kv/errors.py +561 -0
- build/lib/moat/kv/exceptions.py +126 -0
- build/lib/moat/kv/mock/__init__.py +101 -0
- build/lib/moat/kv/mock/mqtt.py +159 -0
- build/lib/moat/kv/mock/serf.py +250 -0
- build/lib/moat/kv/mock/tracer.py +63 -0
- build/lib/moat/kv/model.py +1069 -0
- build/lib/moat/kv/obj/__init__.py +646 -0
- build/lib/moat/kv/obj/command.py +241 -0
- build/lib/moat/kv/runner.py +1347 -0
- build/lib/moat/kv/server.py +2809 -0
- build/lib/moat/kv/types.py +513 -0
- debian/moat-kv/usr/lib/python3/dist-packages/docs/source/conf.py +201 -0
- debian/moat-kv/usr/lib/python3/dist-packages/examples/pathify.py +45 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/__init__.py +19 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml +97 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_main.py +91 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/__init__.py +98 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/deletor.py +139 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/__init__.py +444 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/_test.py +166 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/password.py +234 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/root.py +58 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/__init__.py +67 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py +74 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/serf.py +45 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/client.py +1025 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/code.py +236 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/codec.py +11 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/__init__.py +1 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/acl.py +180 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/auth.py +261 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/code.py +293 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/codec.py +186 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/data.py +265 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/dump/__init__.py +143 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/error.py +149 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/internal.py +248 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/job.py +433 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/log.py +53 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/server.py +114 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/type.py +201 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/config.py +46 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/data.py +216 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/errors.py +561 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/exceptions.py +126 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/__init__.py +101 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/mqtt.py +159 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/serf.py +250 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/tracer.py +63 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/model.py +1069 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/__init__.py +646 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/command.py +241 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/runner.py +1347 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/server.py +2809 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/types.py +513 -0
- docs/source/conf.py +201 -0
- examples/pathify.py +45 -0
- moat/kv/__init__.py +1 -0
- moat/kv/_cfg.yaml +97 -0
- moat/kv/_main.py +6 -9
- moat/kv/actor/__init__.py +2 -1
- moat/kv/actor/deletor.py +3 -1
- moat/kv/auth/__init__.py +8 -10
- moat/kv/auth/_test.py +6 -12
- moat/kv/auth/password.py +2 -0
- moat/kv/auth/root.py +2 -0
- moat/kv/backend/__init__.py +1 -0
- moat/kv/backend/mqtt.py +3 -3
- moat/kv/backend/serf.py +1 -0
- moat/kv/client.py +34 -50
- moat/kv/code.py +10 -3
- moat/kv/codec.py +1 -0
- moat/kv/command/acl.py +12 -6
- moat/kv/command/auth.py +5 -2
- moat/kv/command/code.py +10 -23
- moat/kv/command/codec.py +10 -14
- moat/kv/command/data.py +12 -21
- moat/kv/command/dump/__init__.py +4 -2
- moat/kv/command/error.py +5 -12
- moat/kv/command/internal.py +6 -15
- moat/kv/command/job.py +26 -31
- moat/kv/command/log.py +1 -0
- moat/kv/command/server.py +2 -3
- moat/kv/command/type.py +26 -28
- moat/kv/config.py +2 -0
- moat/kv/data.py +8 -7
- moat/kv/errors.py +17 -9
- moat/kv/exceptions.py +1 -7
- moat/kv/mock/__init__.py +9 -5
- moat/kv/mock/mqtt.py +7 -12
- moat/kv/mock/serf.py +6 -9
- moat/kv/mock/tracer.py +2 -4
- moat/kv/model.py +16 -24
- moat/kv/obj/__init__.py +30 -20
- moat/kv/obj/command.py +7 -12
- moat/kv/runner.py +38 -35
- moat/kv/server.py +86 -90
- moat/kv/types.py +5 -8
- {moat_kv-0.70.22.dist-info → moat_kv-0.70.24.dist-info}/METADATA +15 -18
- moat_kv-0.70.24.dist-info/RECORD +137 -0
- {moat_kv-0.70.22.dist-info → moat_kv-0.70.24.dist-info}/WHEEL +1 -1
- moat_kv-0.70.24.dist-info/licenses/LICENSE.txt +14 -0
- moat_kv-0.70.24.dist-info/top_level.txt +9 -0
- moat/kv/_config.yaml +0 -98
- moat_kv-0.70.22.dist-info/LICENSE +0 -3
- moat_kv-0.70.22.dist-info/LICENSE.APACHE2 +0 -202
- moat_kv-0.70.22.dist-info/LICENSE.MIT +0 -20
- moat_kv-0.70.22.dist-info/RECORD +0 -49
- moat_kv-0.70.22.dist-info/top_level.txt +0 -1
moat/kv/command/type.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# command line interface
|
2
|
+
from __future__ import annotations
|
2
3
|
|
3
4
|
import json
|
4
5
|
|
@@ -13,15 +14,9 @@ async def cli():
|
|
13
14
|
|
14
15
|
|
15
16
|
@cli.command()
|
16
|
-
@click.option(
|
17
|
-
|
18
|
-
)
|
19
|
-
@click.option(
|
20
|
-
"-S", "--schema", type=click.File(mode="w", lazy=True), help="Save the schema here"
|
21
|
-
)
|
22
|
-
@click.option(
|
23
|
-
"-y", "--yaml", "yaml_", is_flag=True, help="Write schema as YAML. Default: JSON."
|
24
|
-
)
|
17
|
+
@click.option("-s", "--script", type=click.File(mode="w", lazy=True), help="Save the script here")
|
18
|
+
@click.option("-S", "--schema", type=click.File(mode="w", lazy=True), help="Save the schema here")
|
19
|
+
@click.option("-y", "--yaml", "yaml_", is_flag=True, help="Write schema as YAML. Default: JSON.")
|
25
20
|
@click.argument("path", type=P, nargs=1)
|
26
21
|
@click.pass_obj
|
27
22
|
async def get(obj, path, script, schema, yaml_):
|
@@ -29,7 +24,10 @@ async def get(obj, path, script, schema, yaml_):
|
|
29
24
|
if not len(path):
|
30
25
|
raise click.UsageError("You need a non-empty path.")
|
31
26
|
res = await obj.client._request(
|
32
|
-
action="get_internal",
|
27
|
+
action="get_internal",
|
28
|
+
path=Path("type") + path,
|
29
|
+
iter=False,
|
30
|
+
nchain=obj.meta,
|
33
31
|
)
|
34
32
|
try:
|
35
33
|
r = res.value
|
@@ -51,18 +49,10 @@ async def get(obj, path, script, schema, yaml_):
|
|
51
49
|
@cli.command("set")
|
52
50
|
@click.option("-g", "--good", multiple=True, help="Example for passing values")
|
53
51
|
@click.option("-b", "--bad", multiple=True, help="Example for failing values")
|
54
|
-
@click.option(
|
55
|
-
|
56
|
-
)
|
57
|
-
@click.option(
|
58
|
-
"-s", "--script", type=click.File(mode="r"), help="File with the checking script"
|
59
|
-
)
|
60
|
-
@click.option(
|
61
|
-
"-S", "--schema", type=click.File(mode="r"), help="File with the JSON schema"
|
62
|
-
)
|
63
|
-
@click.option(
|
64
|
-
"-y", "--yaml", "yaml_", is_flag=True, help="load the schema as YAML. Default: JSON"
|
65
|
-
)
|
52
|
+
@click.option("-d", "--data", type=click.File(mode="r"), help="Load metadata from this YAML file.")
|
53
|
+
@click.option("-s", "--script", type=click.File(mode="r"), help="File with the checking script")
|
54
|
+
@click.option("-S", "--schema", type=click.File(mode="r"), help="File with the JSON schema")
|
55
|
+
@click.option("-y", "--yaml", "yaml_", is_flag=True, help="load the schema as YAML. Default: JSON")
|
66
56
|
@click.argument("path", type=P, nargs=1)
|
67
57
|
@click.pass_obj
|
68
58
|
async def set_(obj, path, good, bad, script, schema, yaml_, data):
|
@@ -134,7 +124,10 @@ async def match(obj, path, type_, delete, raw): # pylint: disable=redefined-bui
|
|
134
124
|
y = {}
|
135
125
|
pl = PathLongener()
|
136
126
|
async for r in await obj.client._request(
|
137
|
-
"get_tree_internal",
|
127
|
+
"get_tree_internal",
|
128
|
+
path=Path("match") + path,
|
129
|
+
iter=True,
|
130
|
+
nchain=0,
|
138
131
|
):
|
139
132
|
pl(r)
|
140
133
|
path = r["path"]
|
@@ -154,9 +147,7 @@ async def match(obj, path, type_, delete, raw): # pylint: disable=redefined-bui
|
|
154
147
|
raise click.UsageError("You can only print the raw path when reading a match.")
|
155
148
|
|
156
149
|
if delete:
|
157
|
-
res = await obj.client._request(
|
158
|
-
action="delete_internal", path=Path("type") + path
|
159
|
-
)
|
150
|
+
res = await obj.client._request(action="delete_internal", path=Path("type") + path)
|
160
151
|
if obj.meta:
|
161
152
|
yprint(res, stream=obj.stdout)
|
162
153
|
return
|
@@ -170,7 +161,11 @@ async def match(obj, path, type_, delete, raw): # pylint: disable=redefined-bui
|
|
170
161
|
else:
|
171
162
|
act = "get_internal"
|
172
163
|
res = await obj.client._request(
|
173
|
-
action=act,
|
164
|
+
action=act,
|
165
|
+
value=msg,
|
166
|
+
path=Path("match") + path,
|
167
|
+
iter=False,
|
168
|
+
nchain=obj.meta,
|
174
169
|
)
|
175
170
|
if obj.meta:
|
176
171
|
yprint(res, stream=obj.stdout)
|
@@ -189,7 +184,10 @@ async def list(obj, path): # pylint: disable=redefined-builtin
|
|
189
184
|
y = {}
|
190
185
|
pl = PathLongener()
|
191
186
|
async for r in await obj.client._request(
|
192
|
-
"get_tree_internal",
|
187
|
+
"get_tree_internal",
|
188
|
+
path=Path("type") + path,
|
189
|
+
iter=True,
|
190
|
+
nchain=0,
|
193
191
|
):
|
194
192
|
pl(r)
|
195
193
|
path = r["path"]
|
moat/kv/config.py
CHANGED
moat/kv/data.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
"""
|
2
2
|
Data access
|
3
3
|
"""
|
4
|
+
from __future__ import annotations
|
5
|
+
|
4
6
|
import datetime
|
5
7
|
import os
|
6
8
|
import sys
|
@@ -35,7 +37,8 @@ def add_dates(d):
|
|
35
37
|
continue
|
36
38
|
if start <= v <= stop:
|
37
39
|
d[f"_{k}"] = datetime.datetime.fromtimestamp(v).isoformat(
|
38
|
-
sep=" ",
|
40
|
+
sep=" ",
|
41
|
+
timespec="milliseconds",
|
39
42
|
)
|
40
43
|
|
41
44
|
_add(d)
|
@@ -81,9 +84,7 @@ async def data_get(
|
|
81
84
|
kw.setdefault("nchain", obj.meta)
|
82
85
|
y = {}
|
83
86
|
if internal:
|
84
|
-
res = await obj.client._request(
|
85
|
-
action="get_tree_internal", path=path, iter=True, **kw
|
86
|
-
)
|
87
|
+
res = await obj.client._request(action="get_tree_internal", path=path, iter=True, **kw)
|
87
88
|
else:
|
88
89
|
res = obj.client.get_tree(path, **kw)
|
89
90
|
async for r in res:
|
@@ -182,16 +183,16 @@ def res_update(res, attr: Path, value=None, **kw): # pylint: disable=redefined-
|
|
182
183
|
return val._update(attr, value=value, **kw)
|
183
184
|
|
184
185
|
|
185
|
-
async def node_attr(obj, path,
|
186
|
+
async def node_attr(obj, path, res=None, chain=None, **kw):
|
186
187
|
"""
|
187
188
|
Sub-attr setter.
|
188
189
|
|
189
190
|
Args:
|
190
191
|
obj: command object
|
191
192
|
path: address of the node to change
|
192
|
-
vars_, eval_, path_: the results of `attr_args`
|
193
193
|
res: old node, if it has been read already
|
194
194
|
chain: change chain of node, copied from res if clear
|
195
|
+
**kw: the results of `attr_args`
|
195
196
|
|
196
197
|
Returns the result of setting the attribute.
|
197
198
|
"""
|
@@ -207,7 +208,7 @@ async def node_attr(obj, path, vars_, eval_, path_, res=None, chain=None):
|
|
207
208
|
except AttributeError:
|
208
209
|
chain = None
|
209
210
|
val = NotGiven
|
210
|
-
val = process_args(val,
|
211
|
+
val = process_args(val, **kw)
|
211
212
|
if val is NotGiven:
|
212
213
|
res = await obj.client.delete(path, nchain=obj.meta, chain=chain)
|
213
214
|
else:
|
moat/kv/errors.py
CHANGED
@@ -79,6 +79,8 @@ of this record.
|
|
79
79
|
|
80
80
|
"""
|
81
81
|
|
82
|
+
from __future__ import annotations
|
83
|
+
|
82
84
|
import logging
|
83
85
|
import traceback
|
84
86
|
from collections import defaultdict
|
@@ -212,7 +214,7 @@ class ErrorEntry(AttrClientEntry):
|
|
212
214
|
try:
|
213
215
|
m = message.format(exc=exc, **data)
|
214
216
|
except Exception as exc: # pylint: disable=unused-argument # OH COME ON
|
215
|
-
m = message + f" (FORMAT {exc
|
217
|
+
m = message + f" (FORMAT {exc!r})"
|
216
218
|
else:
|
217
219
|
m = message
|
218
220
|
if m:
|
@@ -304,9 +306,7 @@ class ErrorEntry(AttrClientEntry):
|
|
304
306
|
if value is NotGiven:
|
305
307
|
if self.value is NotGiven:
|
306
308
|
return
|
307
|
-
keep = await self.root.get_error_record(
|
308
|
-
self.subsystem, self.path, create=False
|
309
|
-
)
|
309
|
+
keep = await self.root.get_error_record(self.subsystem, self.path, create=False)
|
310
310
|
if keep is not None:
|
311
311
|
self._real_entry = keep.real_entry
|
312
312
|
await self.move_to_real()
|
@@ -449,7 +449,13 @@ class ErrorRoot(ClientRoot):
|
|
449
449
|
raise RuntimeError(f"This cannot happen: {entry.node} {entry.tock}")
|
450
450
|
|
451
451
|
async def record_working( # pylint: disable=dangerous-default-value
|
452
|
-
self,
|
452
|
+
self,
|
453
|
+
subsystem,
|
454
|
+
path,
|
455
|
+
*,
|
456
|
+
comment=None,
|
457
|
+
data={},
|
458
|
+
force=False,
|
453
459
|
):
|
454
460
|
"""This exception has been fixed.
|
455
461
|
|
@@ -522,7 +528,11 @@ class ErrorRoot(ClientRoot):
|
|
522
528
|
return # owch, but can't be helped
|
523
529
|
|
524
530
|
r = await rec.real_entry.add_exc(
|
525
|
-
self.name,
|
531
|
+
self.name,
|
532
|
+
exc=exc,
|
533
|
+
data=data,
|
534
|
+
comment=comment,
|
535
|
+
message=message,
|
526
536
|
)
|
527
537
|
return r
|
528
538
|
|
@@ -535,9 +545,7 @@ class ErrorRoot(ClientRoot):
|
|
535
545
|
return
|
536
546
|
|
537
547
|
try:
|
538
|
-
del (self._done if entry.resolved else self._active)[entry.subsystem][
|
539
|
-
entry.path
|
540
|
-
]
|
548
|
+
del (self._done if entry.resolved else self._active)[entry.subsystem][entry.path]
|
541
549
|
except KeyError:
|
542
550
|
pass
|
543
551
|
|
moat/kv/exceptions.py
CHANGED
@@ -3,7 +3,7 @@ This module affords all MoaT-KV exceptions.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
# pylint: disable=unnecessary-pass
|
6
|
-
|
6
|
+
from __future__ import annotations
|
7
7
|
|
8
8
|
error_types = {}
|
9
9
|
|
@@ -39,8 +39,6 @@ class ClientError(MoaTKVError):
|
|
39
39
|
|
40
40
|
etype: str = None
|
41
41
|
|
42
|
-
pass
|
43
|
-
|
44
42
|
|
45
43
|
@_typed
|
46
44
|
class ClientChainError(ClientError):
|
@@ -48,8 +46,6 @@ class ClientChainError(ClientError):
|
|
48
46
|
|
49
47
|
etype = "chain"
|
50
48
|
|
51
|
-
pass
|
52
|
-
|
53
49
|
|
54
50
|
@_typed
|
55
51
|
class ClientConnectionError(ClientError):
|
@@ -57,8 +53,6 @@ class ClientConnectionError(ClientError):
|
|
57
53
|
|
58
54
|
etype = "conn"
|
59
55
|
|
60
|
-
pass
|
61
|
-
|
62
56
|
|
63
57
|
class ServerClosedError(ServerError):
|
64
58
|
"""The server closed our connection."""
|
moat/kv/mock/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# from asyncclick.testing import CliRunner
|
2
|
+
from __future__ import annotations
|
2
3
|
import io
|
3
4
|
import logging
|
4
5
|
import shlex
|
@@ -10,9 +11,11 @@ import attr
|
|
10
11
|
from asyncscope import main_scope, scope
|
11
12
|
from moat.src.test import run # pylint:disable=import-error,no-name-in-module
|
12
13
|
from moat.util import ( # pylint:disable=no-name-in-module
|
14
|
+
CFG,
|
13
15
|
OptCtx,
|
14
16
|
attrdict,
|
15
17
|
combine_dict,
|
18
|
+
ensure_cfg,
|
16
19
|
list_ext,
|
17
20
|
load_ext,
|
18
21
|
wrap_main,
|
@@ -27,7 +30,7 @@ try:
|
|
27
30
|
except ImportError:
|
28
31
|
from async_generator import asynccontextmanager
|
29
32
|
|
30
|
-
|
33
|
+
ensure_cfg("moat.kv")
|
31
34
|
|
32
35
|
|
33
36
|
@attr.s
|
@@ -70,7 +73,10 @@ class S:
|
|
70
73
|
|
71
74
|
async with scope.using_scope():
|
72
75
|
c = await scope.service(
|
73
|
-
f"moat.kv.client.{i}.{self._seq}",
|
76
|
+
f"moat.kv.client.{i}.{self._seq}",
|
77
|
+
scc,
|
78
|
+
self.s[i],
|
79
|
+
**cfg,
|
74
80
|
)
|
75
81
|
yield c
|
76
82
|
return
|
@@ -92,6 +98,4 @@ class S:
|
|
92
98
|
if isinstance(args, str):
|
93
99
|
args = args.split(" ")
|
94
100
|
async with scope.using_scope():
|
95
|
-
return await run(
|
96
|
-
"-VV", "kv", "-h", h, "-p", p, *args, do_stdout=do_stdout
|
97
|
-
)
|
101
|
+
return await run("-VV", "kv", "-h", h, "-p", p, *args, do_stdout=do_stdout)
|
moat/kv/mock/mqtt.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
import copy
|
2
3
|
import logging
|
3
4
|
import os
|
@@ -6,7 +7,7 @@ from contextlib import AsyncExitStack, asynccontextmanager
|
|
6
7
|
from functools import partial
|
7
8
|
|
8
9
|
import anyio
|
9
|
-
import mock
|
10
|
+
from unittest import mock
|
10
11
|
import trio
|
11
12
|
from asyncscope import main_scope, scope
|
12
13
|
from moat.mqtt.broker import create_broker
|
@@ -65,7 +66,7 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
65
66
|
pass # test doesn't have autojump_clock fixture
|
66
67
|
|
67
68
|
async def mock_get_host_port(st, host):
|
68
|
-
i = int(host[host.rindex("_") + 1 :])
|
69
|
+
i = int(host[host.rindex("_") + 1 :])
|
69
70
|
s = st.s[i]
|
70
71
|
await s.is_serving
|
71
72
|
for host, port, *_ in s.ports:
|
@@ -122,21 +123,17 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
122
123
|
"backend": "mqtt",
|
123
124
|
"mqtt": {"uri": URI},
|
124
125
|
},
|
125
|
-
}
|
126
|
+
},
|
126
127
|
},
|
127
128
|
{"cfg": TESTCFG},
|
128
129
|
)
|
129
130
|
args_def.pop("init", None)
|
130
131
|
s = Server(name, **args)
|
131
132
|
ex.enter_context(
|
132
|
-
mock.patch.object(
|
133
|
-
s, "_set_tock", new=partial(mock_set_tock, s, s._set_tock)
|
134
|
-
)
|
133
|
+
mock.patch.object(s, "_set_tock", new=partial(mock_set_tock, s, s._set_tock)),
|
135
134
|
)
|
136
135
|
ex.enter_context(
|
137
|
-
mock.patch.object(
|
138
|
-
s, "_get_host_port", new=partial(mock_get_host_port, st)
|
139
|
-
)
|
136
|
+
mock.patch.object(s, "_get_host_port", new=partial(mock_get_host_port, st)),
|
140
137
|
)
|
141
138
|
st.s.append(s)
|
142
139
|
|
@@ -147,9 +144,7 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
147
144
|
await scp.spawn_service(with_broker, st.s[i], ready_evt=evt)
|
148
145
|
evts.append(evt)
|
149
146
|
else:
|
150
|
-
setattr(
|
151
|
-
st, f"run_{i}", partial(scp.spawn_service, with_broker, st.s[i])
|
152
|
-
)
|
147
|
+
setattr(st, f"run_{i}", partial(scp.spawn_service, with_broker, st.s[i]))
|
153
148
|
|
154
149
|
for e in evts:
|
155
150
|
await e.wait()
|
moat/kv/mock/serf.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
import copy
|
2
3
|
import logging
|
3
4
|
import time
|
@@ -6,7 +7,7 @@ from functools import partial
|
|
6
7
|
|
7
8
|
import anyio
|
8
9
|
import attr
|
9
|
-
import mock
|
10
|
+
from unittest import mock
|
10
11
|
import trio
|
11
12
|
from asyncscope import main_scope, scope
|
12
13
|
from asyncserf.stream import SerfEvent
|
@@ -69,7 +70,7 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
69
70
|
self.splits.remove(s)
|
70
71
|
|
71
72
|
async def mock_get_host_port(st, host):
|
72
|
-
i = int(host[host.rindex("_") + 1 :])
|
73
|
+
i = int(host[host.rindex("_") + 1 :])
|
73
74
|
s = st.s[i]
|
74
75
|
await s.is_serving
|
75
76
|
for host, port, *_ in s.ports:
|
@@ -96,7 +97,7 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
96
97
|
logging._startTime = tm()
|
97
98
|
|
98
99
|
ex.enter_context(
|
99
|
-
mock.patch("asyncserf.serf_client", new=partial(mock_serf_client, st))
|
100
|
+
mock.patch("asyncserf.serf_client", new=partial(mock_serf_client, st)),
|
100
101
|
)
|
101
102
|
|
102
103
|
for i in range(n):
|
@@ -121,14 +122,10 @@ async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
|
|
121
122
|
)
|
122
123
|
s = Server(name, **args)
|
123
124
|
ex.enter_context(
|
124
|
-
mock.patch.object(
|
125
|
-
s, "_set_tock", new=partial(mock_set_tock, s, s._set_tock)
|
126
|
-
)
|
125
|
+
mock.patch.object(s, "_set_tock", new=partial(mock_set_tock, s, s._set_tock)),
|
127
126
|
)
|
128
127
|
ex.enter_context(
|
129
|
-
mock.patch.object(
|
130
|
-
s, "_get_host_port", new=partial(mock_get_host_port, st)
|
131
|
-
)
|
128
|
+
mock.patch.object(s, "_get_host_port", new=partial(mock_get_host_port, st)),
|
132
129
|
)
|
133
130
|
st.s.append(s)
|
134
131
|
|
moat/kv/mock/tracer.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
import traceback
|
2
3
|
|
3
4
|
import trio
|
@@ -31,12 +32,9 @@ class Tracer(trio.abc.Instrument):
|
|
31
32
|
if isinstance(exception, Exception):
|
32
33
|
self.etasks.add(task)
|
33
34
|
self._print_with_task("*** task excepted", task, exception)
|
34
|
-
pass
|
35
35
|
|
36
36
|
def before_task_step(self, task):
|
37
|
-
if isinstance(task._next_send, Error) and isinstance(
|
38
|
-
task._next_send.error, Exception
|
39
|
-
):
|
37
|
+
if isinstance(task._next_send, Error) and isinstance(task._next_send.error, Exception):
|
40
38
|
self._print_with_task("*** step resume ERROR", task, task._next_send.error)
|
41
39
|
self.etasks.add(task)
|
42
40
|
elif moat.kill: # pylint: disable=c-extension-no-member # OH COME ON
|
moat/kv/model.py
CHANGED
@@ -9,7 +9,7 @@ from __future__ import annotations
|
|
9
9
|
import weakref
|
10
10
|
from collections import defaultdict
|
11
11
|
from logging import getLogger
|
12
|
-
from typing import Any
|
12
|
+
from typing import Any
|
13
13
|
|
14
14
|
from moat.util import NotGiven, Path, attrdict, create_queue
|
15
15
|
from range_set import RangeSet
|
@@ -39,9 +39,7 @@ class Node:
|
|
39
39
|
tick: int = None
|
40
40
|
_present: RangeSet = None # I have these as valid data. Superset of ``._deleted``.
|
41
41
|
_deleted: RangeSet = None # I have these as no-longer-valid data
|
42
|
-
_reported: RangeSet =
|
43
|
-
None # somebody else reported these missing data for this node
|
44
|
-
)
|
42
|
+
_reported: RangeSet = None # somebody else reported these missing data for this node
|
45
43
|
_superseded: RangeSet = None # I know these once existed, but no more.
|
46
44
|
entries: dict = None
|
47
45
|
tock: int = 0 # tock when node was last observed
|
@@ -371,7 +369,7 @@ class NodeEvent:
|
|
371
369
|
|
372
370
|
"""
|
373
371
|
|
374
|
-
def __init__(self, node: Node, tick: int = None, prev:
|
372
|
+
def __init__(self, node: Node, tick: int = None, prev: NodeEvent = None):
|
375
373
|
self.node = node
|
376
374
|
if tick is None:
|
377
375
|
tick = node.tick
|
@@ -524,13 +522,15 @@ class NodeEvent:
|
|
524
522
|
self.prev = cls.deserialize(msg["prev"], cache=cache)
|
525
523
|
return self
|
526
524
|
|
527
|
-
def attach(self, prev:
|
525
|
+
def attach(self, prev: NodeEvent = None, server=None):
|
528
526
|
"""Copy this node, if necessary, and attach a filtered `prev` chain to it"""
|
529
527
|
if prev is not None:
|
530
528
|
prev = prev.filter(self.node, server=server)
|
531
529
|
if self.prev is not None or prev is not None:
|
532
530
|
self = NodeEvent( # pylint: disable=self-cls-assignment
|
533
|
-
node=self.node,
|
531
|
+
node=self.node,
|
532
|
+
tick=self.tick,
|
533
|
+
prev=prev,
|
534
534
|
)
|
535
535
|
return self
|
536
536
|
|
@@ -538,9 +538,7 @@ class NodeEvent:
|
|
538
538
|
class UpdateEvent:
|
539
539
|
"""Represents an event which updates something."""
|
540
540
|
|
541
|
-
def __init__(
|
542
|
-
self, event: NodeEvent, entry: "Entry", new_value, old_value=NotGiven, tock=None
|
543
|
-
):
|
541
|
+
def __init__(self, event: NodeEvent, entry: Entry, new_value, old_value=NotGiven, tock=None):
|
544
542
|
self.event = event
|
545
543
|
self.entry = entry
|
546
544
|
self.new_value = new_value
|
@@ -611,10 +609,10 @@ class UpdateEvent:
|
|
611
609
|
class Entry:
|
612
610
|
"""This class represents one key/value pair"""
|
613
611
|
|
614
|
-
_parent:
|
612
|
+
_parent: Entry = None
|
615
613
|
name: str = None
|
616
|
-
_path:
|
617
|
-
_root:
|
614
|
+
_path: list[str] = None
|
615
|
+
_root: Entry = None
|
618
616
|
chain: NodeEvent = None
|
619
617
|
SUBTYPE = None
|
620
618
|
SUBTYPES = {}
|
@@ -622,7 +620,7 @@ class Entry:
|
|
622
620
|
|
623
621
|
monitors = None
|
624
622
|
|
625
|
-
def __init__(self, name: str, parent:
|
623
|
+
def __init__(self, name: str, parent: Entry, tock=None):
|
626
624
|
self.name = name
|
627
625
|
self._sub = {}
|
628
626
|
self.monitors = set()
|
@@ -632,7 +630,7 @@ class Entry:
|
|
632
630
|
parent._add_subnode(self)
|
633
631
|
self._parent = weakref.ref(parent)
|
634
632
|
|
635
|
-
def _add_subnode(self, child:
|
633
|
+
def _add_subnode(self, child: Entry):
|
636
634
|
self._sub[child.name] = child
|
637
635
|
|
638
636
|
def __hash__(self):
|
@@ -904,9 +902,7 @@ class Entry:
|
|
904
902
|
if not loading:
|
905
903
|
logger.warning("*** inconsistency ***")
|
906
904
|
logger.warning("Node: %s", self.path)
|
907
|
-
logger.warning(
|
908
|
-
"Current: %s :%s: %r", self.chain, self.tock, self._data
|
909
|
-
)
|
905
|
+
logger.warning("Current: %s :%s: %r", self.chain, self.tock, self._data)
|
910
906
|
logger.warning("New: %s :%s: %r", evt.event, evt.tock, evt_val)
|
911
907
|
if evt.tock < self.tock:
|
912
908
|
if not loading:
|
@@ -934,9 +930,7 @@ class Entry:
|
|
934
930
|
n.seen(t, self)
|
935
931
|
await self.updated(evt)
|
936
932
|
|
937
|
-
async def walk(
|
938
|
-
self, proc, acl=None, max_depth=-1, min_depth=0, _depth=0, full=False
|
939
|
-
):
|
933
|
+
async def walk(self, proc, acl=None, max_depth=-1, min_depth=0, _depth=0, full=False):
|
940
934
|
"""
|
941
935
|
Call coroutine ``proc`` on this node and all its children).
|
942
936
|
|
@@ -960,9 +954,7 @@ class Entry:
|
|
960
954
|
if k is None and not full:
|
961
955
|
continue
|
962
956
|
a = acl.step(k) if acl is not None else None
|
963
|
-
await v.walk(
|
964
|
-
proc, acl=a, max_depth=max_depth, min_depth=min_depth, _depth=_depth
|
965
|
-
)
|
957
|
+
await v.walk(proc, acl=a, max_depth=max_depth, min_depth=min_depth, _depth=_depth)
|
966
958
|
|
967
959
|
def serialize(self, chop_path=0, nchain=2, conv=None):
|
968
960
|
"""Serialize this entry for msgpack.
|