moat-kv 0.70.22__py3-none-any.whl → 0.70.23__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.
Files changed (52) hide show
  1. moat/kv/__init__.py +1 -0
  2. moat/kv/_cfg.yaml +97 -0
  3. moat/kv/_main.py +6 -9
  4. moat/kv/client.py +34 -50
  5. moat/kv/code.py +10 -3
  6. moat/kv/codec.py +1 -0
  7. moat/kv/config.py +2 -0
  8. moat/kv/data.py +8 -7
  9. moat/kv/errors.py +17 -9
  10. moat/kv/exceptions.py +1 -7
  11. moat/kv/model.py +16 -24
  12. moat/kv/runner.py +38 -35
  13. moat/kv/server.py +86 -90
  14. moat/kv/types.py +5 -8
  15. {moat_kv-0.70.22.dist-info → moat_kv-0.70.23.dist-info}/METADATA +15 -18
  16. moat_kv-0.70.23.dist-info/RECORD +19 -0
  17. {moat_kv-0.70.22.dist-info → moat_kv-0.70.23.dist-info}/WHEEL +1 -1
  18. moat_kv-0.70.23.dist-info/licenses/LICENSE.txt +14 -0
  19. moat/kv/_config.yaml +0 -98
  20. moat/kv/actor/__init__.py +0 -97
  21. moat/kv/actor/deletor.py +0 -137
  22. moat/kv/auth/__init__.py +0 -446
  23. moat/kv/auth/_test.py +0 -172
  24. moat/kv/auth/password.py +0 -232
  25. moat/kv/auth/root.py +0 -56
  26. moat/kv/backend/__init__.py +0 -66
  27. moat/kv/backend/mqtt.py +0 -74
  28. moat/kv/backend/serf.py +0 -44
  29. moat/kv/command/__init__.py +0 -1
  30. moat/kv/command/acl.py +0 -174
  31. moat/kv/command/auth.py +0 -258
  32. moat/kv/command/code.py +0 -306
  33. moat/kv/command/codec.py +0 -190
  34. moat/kv/command/data.py +0 -274
  35. moat/kv/command/dump/__init__.py +0 -141
  36. moat/kv/command/error.py +0 -156
  37. moat/kv/command/internal.py +0 -257
  38. moat/kv/command/job.py +0 -438
  39. moat/kv/command/log.py +0 -52
  40. moat/kv/command/server.py +0 -115
  41. moat/kv/command/type.py +0 -203
  42. moat/kv/mock/__init__.py +0 -97
  43. moat/kv/mock/mqtt.py +0 -164
  44. moat/kv/mock/serf.py +0 -253
  45. moat/kv/mock/tracer.py +0 -65
  46. moat/kv/obj/__init__.py +0 -636
  47. moat/kv/obj/command.py +0 -246
  48. moat_kv-0.70.22.dist-info/LICENSE +0 -3
  49. moat_kv-0.70.22.dist-info/LICENSE.APACHE2 +0 -202
  50. moat_kv-0.70.22.dist-info/LICENSE.MIT +0 -20
  51. moat_kv-0.70.22.dist-info/RECORD +0 -49
  52. {moat_kv-0.70.22.dist-info → moat_kv-0.70.23.dist-info}/top_level.txt +0 -0
moat/kv/mock/serf.py DELETED
@@ -1,253 +0,0 @@
1
- import copy
2
- import logging
3
- import time
4
- from contextlib import AsyncExitStack, asynccontextmanager
5
- from functools import partial
6
-
7
- import anyio
8
- import attr
9
- import mock
10
- import trio
11
- from asyncscope import main_scope, scope
12
- from asyncserf.stream import SerfEvent
13
- from moat.util import NotGiven, ValueEvent, attrdict, combine_dict, create_queue
14
-
15
- from moat.kv.codec import unpacker
16
- from moat.kv.mock import S as _S
17
- from moat.kv.server import Server
18
-
19
- logger = logging.getLogger(__name__)
20
-
21
- otm = time.time
22
-
23
- from . import CFG
24
-
25
-
26
- @asynccontextmanager
27
- async def stdtest(n=1, run=True, ssl=False, tocks=20, **kw):
28
- C_OUT = CFG.get("_stdout", NotGiven)
29
- if C_OUT is not NotGiven:
30
- del CFG["_stdout"]
31
- TESTCFG = copy.deepcopy(CFG["kv"])
32
- TESTCFG.server.port = None
33
- TESTCFG.server.backend = "serf"
34
- TESTCFG.root = "test"
35
- if C_OUT is not NotGiven:
36
- CFG["_stdout"] = C_OUT
37
- TESTCFG["_stdout"] = C_OUT
38
-
39
- if ssl:
40
- import ssl
41
-
42
- import trustme
43
-
44
- ca = trustme.CA()
45
- cert = ca.issue_server_cert("127.0.0.1")
46
- server_ctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
47
- client_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
48
- ca.configure_trust(client_ctx)
49
- cert.configure_cert(server_ctx)
50
- else:
51
- server_ctx = client_ctx = False
52
-
53
- clock = trio.lowlevel.current_clock()
54
- clock.autojump_threshold = 0.0
55
- # clock.rate = 5
56
-
57
- @attr.s
58
- class S(_S):
59
- splits = attr.ib(factory=set)
60
- serfs = attr.ib(factory=set)
61
-
62
- def split(self, s):
63
- assert s not in self.splits
64
- logger.debug("Split: add %d", s)
65
- self.splits.add(s)
66
-
67
- def join(self, s):
68
- logger.debug("Split: join %d", s)
69
- self.splits.remove(s)
70
-
71
- async def mock_get_host_port(st, host):
72
- i = int(host[host.rindex("_") + 1 :]) # noqa: E203
73
- s = st.s[i]
74
- await s.is_serving
75
- for host, port, *_ in s.ports:
76
- if host == "::" or host[0] != ":":
77
- return host, port
78
-
79
- def tm():
80
- try:
81
- return trio.current_time()
82
- except RuntimeError:
83
- return otm()
84
-
85
- async def mock_set_tock(self, old):
86
- assert self._tock < tocks, "Test didn't terminate. Limit:" + str(tocks)
87
- await old()
88
-
89
- async with main_scope("moat.kv.test.serf") as scp:
90
- tg = scp._tg
91
- st = S(tg, client_ctx)
92
- async with AsyncExitStack() as ex:
93
- st.ex = ex # pylint: disable=attribute-defined-outside-init
94
- ex.enter_context(mock.patch("time.time", new=tm))
95
- ex.enter_context(mock.patch("time.monotonic", new=tm))
96
- logging._startTime = tm()
97
-
98
- ex.enter_context(
99
- mock.patch("asyncserf.serf_client", new=partial(mock_serf_client, st))
100
- )
101
-
102
- for i in range(n):
103
- name = "test_" + str(i)
104
- args = kw.get(name, kw.get("args", attrdict()))
105
- args["cfg"] = combine_dict(
106
- args.get("cfg", {}),
107
- {
108
- "kv": {
109
- "conn": {"ssl": client_ctx},
110
- },
111
- "server": {
112
- "bind_default": {
113
- "host": "127.0.0.1",
114
- "port": i + 50120,
115
- "ssl": server_ctx,
116
- },
117
- "serf": {"i": i},
118
- },
119
- },
120
- TESTCFG,
121
- )
122
- s = Server(name, **args)
123
- ex.enter_context(
124
- mock.patch.object(
125
- s, "_set_tock", new=partial(mock_set_tock, s, s._set_tock)
126
- )
127
- )
128
- ex.enter_context(
129
- mock.patch.object(
130
- s, "_get_host_port", new=partial(mock_get_host_port, st)
131
- )
132
- )
133
- st.s.append(s)
134
-
135
- async def with_serf(s, *a, **k):
136
- s._scope = scope.get()
137
- return await s._scoped_serve(*a, **k)
138
-
139
- evts = []
140
- for i in range(n):
141
- if kw.get("run_" + str(i), run):
142
- evt = anyio.Event()
143
- await scp.spawn_service(with_serf, st.s[i], ready_evt=evt)
144
- evts.append(evt)
145
- for e in evts:
146
- await e.wait()
147
- try:
148
- yield st
149
- finally:
150
- with anyio.fail_after(2, shield=True):
151
- logger.info("Runtime: %s", clock.current_time())
152
- tg.cancel_scope.cancel()
153
- logger.info("End")
154
- pass # unwinding ex:AsyncExitStack
155
-
156
-
157
- @asynccontextmanager
158
- async def mock_serf_client(master, **cfg):
159
- async with scope.using_scope():
160
- ms = MockServ(master, **cfg)
161
- master.serfs.add(ms)
162
- ms._scope = scope.get() # pylint:disable=attribute-defined-outside-init
163
- try:
164
- yield ms
165
- finally:
166
- master.serfs.remove(ms)
167
- pass # terminating mock_serf_client nursery
168
-
169
-
170
- class MockServ:
171
- def __init__(self, master, **cfg):
172
- self.cfg = cfg
173
- self._tg = scope._tg
174
- self.streams = {}
175
- self._master = master
176
-
177
- def __hash__(self):
178
- return id(self)
179
-
180
- async def spawn(self, fn, *args, **kw):
181
- async def run(evt):
182
- with anyio.CancelScope() as sc:
183
- await evt.set(sc)
184
- await fn(*args, **kw)
185
-
186
- evt = ValueEvent()
187
- self._tg.spawn(run, evt)
188
- return await evt.get()
189
-
190
- async def event(self, name, payload, coalesce=True):
191
- try:
192
- logger.debug("SERF:%s: %r", name, unpacker(payload))
193
- except Exception:
194
- logger.debug("SERF:%s: %r (raw)", name, payload)
195
- assert not coalesce, "'coalesce' must be cleared!"
196
-
197
- i_self = self.cfg.get("i", 0)
198
- for s in list(self._master.serfs):
199
- i_s = s.cfg.get("i", 0)
200
- for x in self._master.splits:
201
- if (i_s < x) != (i_self < x):
202
- break
203
- else:
204
- n = tuple(name.split("."))
205
- while n:
206
- sl = s.streams.get(n, ())
207
- for sn in sl:
208
- await sn.q.put((name, payload))
209
- n = n[:-1]
210
-
211
- def stream(self, typ):
212
- """compat for supporting asyncactor"""
213
- if not typ.startswith("user:"):
214
- raise RuntimeError("not supported")
215
- typ = typ[5:]
216
- return self.serf_mon(typ)
217
-
218
- def serf_mon(self, typ):
219
- if "," in typ:
220
- raise RuntimeError("not supported")
221
- s = MockSerfStream(self, "user:" + typ)
222
- return s
223
-
224
- async def serf_send(self, typ, payload):
225
- """compat for supporting asyncactor"""
226
- return await self.event(typ, payload)
227
-
228
-
229
- class MockSerfStream:
230
- q = None
231
-
232
- def __init__(self, serf, typ):
233
- self.serf = serf
234
- assert typ.startswith("user:")
235
- self.typ = tuple(typ[5:].split("."))
236
-
237
- async def __aenter__(self):
238
- self.q = create_queue(100)
239
- self.serf.streams.setdefault(self.typ, []).append(self)
240
- return self
241
-
242
- async def __aexit__(self, *tb):
243
- self.serf.streams[self.typ].remove(self)
244
- del self.q
245
-
246
- def __aiter__(self):
247
- return self
248
-
249
- async def __anext__(self):
250
- res = await self.q.get()
251
- evt = SerfEvent(self)
252
- evt.topic, evt.payload = res
253
- return evt
moat/kv/mock/tracer.py DELETED
@@ -1,65 +0,0 @@
1
- import traceback
2
-
3
- import trio
4
- from outcome import Error
5
-
6
- import moat
7
-
8
- moat.kill = False
9
-
10
- import logging
11
-
12
- logger = logging.getLogger("TRACE")
13
- e = logger.error
14
-
15
-
16
- class Tracer(trio.abc.Instrument):
17
- def __init__(self):
18
- super().__init__()
19
- self.etasks = set()
20
-
21
- def _print_with_task(self, msg, task, err=None):
22
- # repr(task) is perhaps more useful than task.name in general,
23
- # but in context of a tutorial the extra noise is unhelpful.
24
- if err is not None:
25
- e("%s: %s %s", msg, task.name, repr(err))
26
- traceback.print_exception(type(err), err, err.__traceback__)
27
- else:
28
- e("%s: %s", msg, task.name)
29
-
30
- def nursery_end(self, task, exception):
31
- if isinstance(exception, Exception):
32
- self.etasks.add(task)
33
- self._print_with_task("*** task excepted", task, exception)
34
- pass
35
-
36
- def before_task_step(self, task):
37
- if isinstance(task._next_send, Error) and isinstance(
38
- task._next_send.error, Exception
39
- ):
40
- self._print_with_task("*** step resume ERROR", task, task._next_send.error)
41
- self.etasks.add(task)
42
- elif moat.kill: # pylint: disable=c-extension-no-member # OH COME ON
43
- self._print_with_task("*** step resume", task)
44
-
45
- def task_scheduled(self, task):
46
- e("SCHED %r", task)
47
-
48
- def task_exited(self, task):
49
- self._print_with_task("*** task exited", task)
50
- self.etasks.discard(task)
51
-
52
- def before_io_wait(self, timeout):
53
- if timeout > 10000 and self.etasks:
54
- e("\n\n\n\n\n\n\n\n\n\n")
55
- e("*** ERROR: lock-out, killing off error tasks")
56
- e("\n\n\n\n")
57
- for t in self.etasks:
58
- if t._next_send_fn is None:
59
- self._print_with_task("!!! Killing", t)
60
- t._runner.reschedule(t, Error(RuntimeError("*** Locked ***")))
61
- else:
62
- self._print_with_task("??? already scheduled", t)
63
-
64
-
65
- # trio.run(main_, instruments=[Tracer()])