Make documentation standalone and generalize examples
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"""Who may see a device's camera: superusers only, or every member too.
|
||||
|
||||
openpanel ROADMAP C4. ``viewers`` on a device covers its ``image`` and
|
||||
``viewers`` on a device covers its ``image`` and
|
||||
``video`` messages, their bytes, frames on the socket and its live view. A
|
||||
device credential is bounded by its dashboards instead.
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Cameras on a device: frames over its socket, demand, and what a screen fetches.
|
||||
|
||||
openpanel ROADMAP C1. A device reports a ``camera`` port that sends only while
|
||||
A device reports a ``camera`` port that sends only while
|
||||
somebody wants it. Demand is what the viewer sockets want plus what running
|
||||
flows read, mapped onto the device's on-demand ports and sent to its socket.
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Live view: WebRTC signalling relayed between a viewer's socket and a device's.
|
||||
|
||||
openpanel ROADMAP L1. The server routes by session, holds a device to two
|
||||
The server routes by session, holds a device to two
|
||||
viewers, ends a session when either socket goes or no answer comes, and hands
|
||||
out TURN credentials in coturn's REST scheme.
|
||||
"""
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
"""What the house port needed from the built-in nodes.
|
||||
|
||||
Three additions, each with a device behind it: an MQTT filter that actually
|
||||
routes what it subscribed to, a value lifted out of the object a device wraps
|
||||
it in, and a wait that differs per message because a shutter takes longer to
|
||||
come up than to go down.
|
||||
"""
|
||||
"""Device messaging with MQTT filters, wrapped values and per-message delays."""
|
||||
|
||||
from fluksio.flow.messages import DType, MessageSpec
|
||||
from fluksio.flow.nodes import MqttNode
|
||||
|
||||
@@ -211,11 +211,8 @@ def test_only_advisory_codes_are_flagged_advisory():
|
||||
def test_a_producer_that_cannot_run_does_not_strand_its_consumer():
|
||||
"""One wave, two producers of one consumer, and one of them never ready.
|
||||
|
||||
The house's shape: a battery reading wakes the boiler arbiter and the
|
||||
watering-pump trigger in the same wave, and the DMX encoder reads both. The
|
||||
pump waits on a pulse that only exists at 02:00, so it is never ready — and
|
||||
passing over it used to leave the encoder unreachable, which put every
|
||||
boiler and plug command into its message and no further.
|
||||
The ready producer must reach its consumer even when a sibling is
|
||||
waiting for an input. The consumer can use that sibling's stored value.
|
||||
"""
|
||||
ran = []
|
||||
|
||||
@@ -268,10 +265,8 @@ def test_a_producer_that_cannot_run_does_not_strand_its_consumer():
|
||||
def test_a_quiet_producer_does_not_veto_a_noisy_sibling():
|
||||
"""Two report-by-exception producers, one consumer, and only one with news.
|
||||
|
||||
The house reads both boilers into one DMX encoder through `rbe` nodes. The
|
||||
kitchen boiler is unchanged almost always, so it returns nothing — and
|
||||
while that held the encoder's dependency count up, the main boiler's
|
||||
command reached its message and got no further.
|
||||
A producer that publishes nothing must not block a shared consumer
|
||||
from processing its sibling's new value.
|
||||
"""
|
||||
ran = []
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ def test_a_service_comes_back_and_its_url_follows(monkeypatch):
|
||||
async def scenario() -> None:
|
||||
agent = Agent()
|
||||
agent.worker = RemoteWorker(
|
||||
name="amcomp",
|
||||
name="gpu-worker",
|
||||
labels=["gpu"],
|
||||
send=agent.send_json,
|
||||
loop=asyncio.get_running_loop(),
|
||||
host="10.0.0.5",
|
||||
host="192.0.2.5",
|
||||
)
|
||||
hub = RemoteWorkerHub()
|
||||
node = ServiceNode(
|
||||
@@ -78,7 +78,7 @@ def test_a_service_comes_back_and_its_url_follows(monkeypatch):
|
||||
|
||||
hub.attach(agent.worker)
|
||||
await until(lambda: bool(agent.serves()))
|
||||
await until(lambda: url() == "http://10.0.0.5:8110")
|
||||
await until(lambda: url() == "http://192.0.2.5:8110")
|
||||
first = agent.serves()[0]
|
||||
assert first["argv"] == ["serve", "--port", "8110"]
|
||||
assert health[-1] == "ok"
|
||||
@@ -88,7 +88,7 @@ def test_a_service_comes_back_and_its_url_follows(monkeypatch):
|
||||
await until(lambda: url() == "")
|
||||
assert "degraded" in health[health.index("ok") :]
|
||||
await until(lambda: len(agent.serves()) == 2)
|
||||
await until(lambda: url() == "http://10.0.0.5:8110")
|
||||
await until(lambda: url() == "http://192.0.2.5:8110")
|
||||
|
||||
# Stopping the flow ends the call on the worker, and empties the url.
|
||||
await node.stop()
|
||||
@@ -110,7 +110,7 @@ def test_a_service_that_never_gets_healthy_reads_down(monkeypatch):
|
||||
async def scenario() -> None:
|
||||
agent = Agent()
|
||||
agent.worker = RemoteWorker(
|
||||
name="amcomp",
|
||||
name="gpu-worker",
|
||||
labels=["gpu"],
|
||||
send=agent.send_json,
|
||||
loop=asyncio.get_running_loop(),
|
||||
|
||||
@@ -116,11 +116,7 @@ def test_one_flows_failure_does_not_stand_another_down():
|
||||
|
||||
|
||||
def test_two_tasks_on_one_flow_do_not_spend_each_others_budget():
|
||||
"""The house's power flow: an MQTT subscriber and its keepalive publisher.
|
||||
|
||||
Both die with the same broker. Sharing one budget meant the flow was stood
|
||||
down after half the restarts either task was allowed on its own.
|
||||
"""
|
||||
"""A subscriber and publisher each get a full restart budget."""
|
||||
tries = {"sub": 0, "pub": 0}
|
||||
|
||||
def crasher(which: str):
|
||||
|
||||
Reference in New Issue
Block a user