plesty.server.services.agent

The bench agent: runs plesty-server commands for a remote plesty.bench client.

A ZMQ ROUTER on the agent port (5550) speaking the plesty-lib device-server wire. Three request types — describe, exec, fetch — documented in plesty.bench.client. exec runs the click application in-process with its output captured, with the agent’s own --home/ -f prepended, so every command the CLI has is remote with nothing to keep in sync. Each request is handled on a worker thread (a start waits for its probe; a describe must not wait behind it); replies go back through the socket thread, since a ZMQ socket belongs to one thread.

Trust model: the bench network, like the device servers — a shared token (--token / PLESTY_BENCH_TOKEN) checked on every exec/fetch, fetch confined to the bench home, no agent/gui through exec.

Attributes

DEFAULT_BIND

TOKEN_ENV

FORBIDDEN

FETCH_LIMIT

Classes

Agent

Serve plesty.bench clients for one bench.

Functions

serve_in_thread(→ tuple[threading.Thread, threading.Event])

Run agent on a daemon thread; returns the thread and its stop event.

_ok(→ dict[str, Any])

_error(→ dict[str, Any])

_frame(→ bytes)

_version(→ str)

Module Contents

plesty.server.services.agent.DEFAULT_BIND = 'tcp://*:5550'
plesty.server.services.agent.TOKEN_ENV = 'PLESTY_BENCH_TOKEN'
plesty.server.services.agent.FORBIDDEN
plesty.server.services.agent.FETCH_LIMIT = 16777216
class plesty.server.services.agent.Agent(home: plesty.server.model.home.Home, fleet_path: str | os.PathLike[str] | None = None, bind: str = DEFAULT_BIND, token: str | None = None, workers: int = 4)

Serve plesty.bench clients for one bench.

Configure the agent.

Parameters:
  • home (plesty.server.model.home.Home) – The bench home every command runs against.

  • fleet_path (str | os.PathLike[str] | None) – Fleet file passed to every command (-f), or None.

  • bind (str) – ZMQ endpoint to bind.

  • token (str | None) – Shared secret; None reads PLESTY_BENCH_TOKEN; empty means no check (a bench on a trusted network).

  • workers (int) – Concurrent requests.

home
fleet_path
bind = 'tcp://*:5550'
token
workers = 4
bound: str | None = None
served = 0
handle(message: Any) dict[str, Any]

Answer one decoded request (pure; no socket involved).

Parameters:

message (Any)

Return type:

dict[str, Any]

description() dict[str, Any]

What describe returns.

Return type:

dict[str, Any]

exec(argv: collections.abc.Sequence[Any]) dict[str, Any]

Run plesty-server <argv> in-process against this bench; capture everything.

Parameters:

argv (collections.abc.Sequence[Any])

Return type:

dict[str, Any]

fetch(path: str) dict[str, Any]

Read a file under the bench home; path is relative to it.

Parameters:

path (str)

Return type:

dict[str, Any]

serve(stop: threading.Event, poll_ms: int = 100, max_replies: int | None = None) int

Bind and answer requests until stop is set; returns the number answered.

Parameters:
  • stop (threading.Event) – Set to end the loop.

  • poll_ms (int) – Socket poll interval.

  • max_replies (int | None) – Stop once this many replies went out (tests).

Return type:

int

plesty.server.services.agent.serve_in_thread(agent: Agent, stop: threading.Event | None = None) tuple[threading.Thread, threading.Event]

Run agent on a daemon thread; returns the thread and its stop event.

Parameters:
  • agent (Agent)

  • stop (threading.Event | None)

Return type:

tuple[threading.Thread, threading.Event]

plesty.server.services.agent._ok(result: Any) dict[str, Any]
Parameters:

result (Any)

Return type:

dict[str, Any]

plesty.server.services.agent._error(message: str, kind: str) dict[str, Any]
Parameters:
  • message (str)

  • kind (str)

Return type:

dict[str, Any]

plesty.server.services.agent._frame(reply: dict[str, Any]) bytes
Parameters:

reply (dict[str, Any])

Return type:

bytes

plesty.server.services.agent._version() str
Return type:

str