maxwelllink.sockets package

Socket hubs connecting MaxwellLink EM solvers to molecular drivers.

The package is organized as follows:

protocol.py                     frozen byte formats (i-PI + AGG frames)
sockets.py                      DummySocketHub base + concrete SocketHub
aggregated.py                   AggregatedSocketHub + bridge transport
_meep_hub_base.py               shared Meep MXLINIT layer (mixin + proxy)
susceptibility.py               SusceptibilitySocketHub (Meep, direct drivers)
aggregated_susceptibility.py    AggregatedSusceptibilitySocketHub (Meep, bridges)

Attributes are loaded lazily so that importing maxwelllink.sockets stays cheap for driver-side processes.

class maxwelllink.sockets.AggregatedSocketHub[source]

Bases: SocketHub

EM-side hub that aggregates multiple molecule requests into one bridge link.

This class keeps the same public methods used by MaxwellLink solvers (register_molecule_return_id, wait_until_bound, all_bound, step_barrier) while mapping many molecule IDs onto a smaller number of bridge connections.

Molecules are assigned to a bridge group through init_payload["aggregate_group"]. All molecules sharing the same group are sent together to one LocalSocketHubBridge.

Parameters:
  • host (str or None, optional) – Interface to bind the upstream TCP server to. None, "", or "0.0.0.0" bind all interfaces; bridges then connect back over 127.0.0.1.

  • port (int or None, default: 31415) – TCP port for the upstream server.

  • timeout (float, default: 60000.0) – Default operation timeout (seconds) used for binding and stepping.

  • latency (float, default: 0.01) – Polling interval (seconds) for the bind/step loops.

__init__(host=None, port=31415, timeout=60000.0, latency=0.01)[source]

Initialize the socket hub.

Parameters:
  • host (str or None, default: None) – Host address for AF_INET sockets. Ignored when using a UNIX socket.

  • port (int or None, default: 31415) – TCP port for AF_INET sockets. Ignored for UNIX sockets.

  • unixsocket (str or None, default: None) – Path (or name under /tmp/socketmxl_*) for a UNIX domain socket. When provided, host and port are ignored.

  • timeout (float, default: 60000.0) – Socket timeout (seconds) for client operations.

  • latency (float, default: 0.01) – Polling sleep (seconds) between hub sweeps; can be very small for local runs.

add_bridge(local_unixsocket)[source]

Create, start, and return one hub-owned local UNIX-socket bridge.

This is the convenience entry point intended for minimal edits when migrating an existing single-layer SocketHub script to the new two-layer transport.

Parameters:

local_unixsocket (str) – Non-empty downstream UNIX-socket address local drivers connect to.

Returns:

A started handle wrapping the new node-local bridge.

Return type:

AggregatedBridge

Raises:

ValueError – If local_unixsocket is empty or already owned by another bridge on this hub.

all_bound(molecule_ids, require_init=True)

Check if all given molecule IDs are bound (and optionally initialized).

Parameters:
  • molecule_ids (iterable of int) – Molecule IDs to check.

  • require_init (bool, default: True) – Also require that clients completed INIT.

Returns:

True if all are bound (and initialized if requested), else False.

Return type:

bool

graceful_shutdown(reason=None, wait=2.0)

Politely ask all connected drivers to exit and wait briefly for BYE.

Parameters:
  • reason (str or None, optional) – Optional reason to log for shutdown.

  • wait (float, default: 2.0) – Seconds to wait for clean replies.

init_remote_bridges(molecules, *, molecules_per_bridge, unix_prefix='bridge_', save_file='aggregation.json')[source]

Partition molecules across remote bridge groups and save a manifest.

This helper does not start any bridge threads locally. Instead it assigns molecule.init_payload["aggregate_group"] for each molecule and writes one JSON manifest that bridge-node scripts can consume via run_bridge_node().

Parameters:
  • molecules (molecule or iterable of molecules) – Molecules to distribute across remote bridges.

  • molecules_per_bridge (int) – Maximum number of molecules assigned to one bridge.

  • unix_prefix (str, default: "bridge_") – Prefix used to generate downstream UNIX socket names f"{unix_prefix}{idx}".

  • save_file (str, default: "aggregation.json") – Path where the bridge manifest should be written.

Returns:

The generated bridge specifications in order.

Return type:

list[RemoteBridgeSpec]

Raises:

ValueError – If no molecules are supplied or molecules_per_bridge is not a positive integer.

Notes

This method records the generated specs on self.remote_bridges and the full manifest on self.remote_bridge_info as a side effect, but does not start any bridge threads.

register_molecule(molecule_id)

Reserve a slot for a given molecule ID (client may connect later).

Parameters:

molecule_id (int) – Molecule ID to register.

Raises:

ValueError – If the molecule ID is already registered.

Return type:

None

register_molecule_return_id()

Reserve a slot for a molecule and return an auto-assigned ID.

Returns:

The assigned unique molecule ID.

Return type:

int

step_barrier(requests, timeout=None)[source]

Dispatch all requested fields group-by-group and collect grouped replies.

Parameters:
  • requests (dict[int, dict]) – Mapping from molecule ID to a request dict with keys: - "efield_au" : array-like (3,) field vector in a.u. - "init" : dict, optional INIT payload for a first bind.

  • timeout (float, optional) – Maximum time (seconds) to wait for every group to reply. Defaults to the hub’s timeout setting.

Returns:

Mapping molid -> {"amp": ndarray(3,), "extra": bytes}, matching the SocketHub.step_barrier contract. Returns {} when paused, when a molecule is not yet bound, or on a mid-step disconnect or timeout.

Return type:

dict[int, dict]

Raises:

RuntimeError – If a bridge replies with the wrong set of molecule ids.

Notes

A single pending group is served by a direct blocking receive; multiple groups are awaited on the aggregate selector so whichever bridge becomes readable first is collected next.

stop()[source]

Stop the aggregate hub and clean up bridge groups coherently.

The base SocketHub.stop() assumes one client per molecule, which is not true here. This override shuts down each bridge once and clears all molecule bindings associated with that bridge.

wait_until_bound(init_payloads, require_init=True, timeout=None)[source]

Wait until all requested molecules are served by initialized bridges.

Molecules are grouped through init_payload["aggregate_group"] and each group must be backed by exactly one connected bridge.

Parameters:
  • init_payloads (dict[int, dict]) – Mapping from molecule ID to INIT payload to use on bind.

  • require_init (bool, default: True) – Also require that each backing bridge completed its AGGINIT handshake.

  • timeout (float or None, optional) – Maximum time to wait (seconds). When None (the default) this method waits indefinitely — the hub-wide self.timeout is not applied here (matching the base-class behavior).

Returns:

True if every requested molecule became bound (and, when require_init is set, initialized) within the time limit, else False.

Return type:

bool

class maxwelllink.sockets.AggregatedSusceptibilitySocketHub[source]

Bases: SusceptibilitySocketHub

Process-backed aggregate hub for Meep MXLSocketSusceptibility.

Same user-facing surface as SusceptibilitySocketHub (endpoint fields, rank_stats, lorentzian_conversion, stop); the downstream transport runs through aggregate bridges instead of direct driver sockets, and this subclass adds the bridge manifest plus the bridge/driver launch-command helpers.

Parameters:
  • host (str or None, optional) – Interface to bind the upstream TCP server to. None, "", "0.0.0.0", or "::" bind all interfaces; peers connect back over 127.0.0.1.

  • port (int or None, default: 31415) – TCP port for the upstream server. None falls back to 31415 and 0 selects an ephemeral port.

  • timeout (float, default: 60000.0) – Operation timeout (seconds) for binding and stepping.

  • latency (float, default: 0.05) – Polling interval (seconds) for the bind/step loops.

  • num_bridges (int, default: 10) – Initial number of aggregate bridge groups.

  • unix_prefix (str, default: "mxl_bridge_") – Prefix used to generate aggregate bridge group ids.

  • bridge_manifest (str, default: "mxl_bridge_manifest.json") – Path the bridge manifest is written to after startup.

  • init_grace_seconds (float, default: 0.5) – Grace period (seconds) for collecting the first burst of rank INITs when the expected molecule total is not announced up front.

  • unixsocket (str or None, optional) – Reserved for API symmetry; must be falsy (TCP upstream only).

Raises:
  • ValueError – If unixsocket is provided.

  • RuntimeError – If the child hub process fails to start.

__init__(host=None, port=31415, timeout=60000.0, latency=0.05, num_bridges=10, unix_prefix='mxl_bridge_', bridge_manifest='mxl_bridge_manifest.json', init_grace_seconds=0.5, unixsocket=None)[source]

Initialize the proxy-side state shared by every process-backed hub.

Concrete hubs validate their own arguments, call this, set any extra attributes, and then call _start_server_process(). Pre-setting the lifecycle attributes here keeps stop() and __del__ safe even when a subclass __init__ fails before the child is launched.

Parameters:
  • timeout (float) – Socket timeout (seconds) passed to the child server.

  • latency (float) – Polling interval (seconds) passed to the child server.

  • host (str | None)

  • port (int | None)

  • num_bridges (int)

  • unix_prefix (str)

  • bridge_manifest (str)

  • init_grace_seconds (float)

  • unixsocket (str | None)

bridge_command(idx, *, info=None)[source]

Build the shell command that launches one aggregate bridge node.

Parameters:
  • idx (int) – Zero-based bridge index within the manifest.

  • info (str or None, optional) – Manifest path to reference. Defaults to self.bridge_manifest.

Return type:

str

property bridge_info: dict

A copy of the manifest reported by the child hub (may be empty).

property bridge_specs: list[dict]

A copy of the manifest’s bridges list (empty when unavailable).

driver_command_template(*, omega_au, mu0_au, orientation)[source]

Build the shell template that launches one SHO driver against a socket.

Returns a /bin/bash -c ... command with a {unixsocket} placeholder. The wrapper waits for the UNIX socket to appear, jitters its start, and restarts the driver until it exits cleanly or the timeout (clamped to [30, 600] seconds) elapses.

Parameters:
  • omega_au (float)

  • mu0_au (float)

  • orientation (int)

Return type:

str

init_remote_bridges(susceptibility=None, *, molecules_per_bridge, unix_prefix='bridge_', save_file='aggregation.json')[source]

Configure delayed bridge partitioning for MXLSocketSusceptibility.

Meep generates the actual socket molecule ids later, during its first polarization update, so this method only records the bridge policy (and forwards it to the child hub). The child writes the final manifest to save_file once MXLINIT reports expected_total_molecules; any stale save_file is removed up front on the MPI master.

Parameters:
  • susceptibility (object, optional) – Accepted and ignored, for API symmetry with AggregatedSocketHub.init_remote_bridges().

  • molecules_per_bridge (int) – Target number of socket molecules per aggregate bridge.

  • unix_prefix (str, default: "bridge_") – Prefix used to generate downstream UNIX-socket names.

  • save_file (str or path-like, default: "aggregation.json") – Path the finalized bridge manifest will be written to.

Returns:

Always empty; the concrete bridge specs are only known later and are written to save_file by the child hub.

Return type:

list[RemoteBridgeSpec]

Raises:

ValueError – If molecules_per_bridge is not a positive integer.

lorentzian_conversion(frequency, sigma, resolution, *, gamma=0.0, dimensions=1, time_units_fs=0.1, mu0_au=187.0819866, orientation=0)

Convert a Meep Lorentzian susceptibility to SHO driver parameters.

The numerical mapping is lorentzian_to_sho_parameters(); this template adds the launch command from _driver_command_for() (targeting this hub’s transport), prints a short report on the MPI master, and merges any _conversion_extras() into the result.

Returns:

{"rescaling_factor", "driver_command", ...extras} where rescaling_factor is the symmetric bright-state coupling scale to pass to mp.MXLSocketSusceptibility(rescaling_factor=...).

Return type:

dict

Raises:

ValueError – If any argument is outside its documented valid range.

Parameters:
  • frequency (float)

  • sigma (float)

  • resolution (float)

  • gamma (float)

  • dimensions (int)

  • time_units_fs (float)

  • mu0_au (float)

  • orientation (int)

property rank_stats: dict[int, dict]

Latest per-Meep-rank statistics from the running server.

Returns:

Mapping from rank to its stats row (molecule_count, steps, requests, peer, …). Empty on non-master ranks.

Return type:

dict[int, dict]

stop()

Stop the hub and tear down the child server process.

Idempotent and safe on non-master ranks. Signals the child via the stop event, joins it, and falls back to terminate() if it does not exit; a final stats drain captures any closing counters.

Return type:

None

write_bridge_manifest(path)[source]

Write the current bridge manifest to path and return it.

Parameters:

path (str)

Return type:

dict

class maxwelllink.sockets.LocalSocketHubBridge[source]

Bases: object

Bridge process/thread that fans out aggregate requests to a local SocketHub.

Upstream:

one TCP connection to AggregatedSocketHub

Downstream:

one ordinary SocketHub using either TCP or UNIX sockets, connected to many existing MaxwellLink socket drivers.

Parameters:
  • group_id (str) – Non-empty aggregate group identifier this bridge serves.

  • upstream_host (str) – Host of the upstream AggregatedSocketHub.

  • upstream_port (int) – TCP port of the upstream hub.

  • timeout (float, default: 60.0) – Operation timeout (seconds) for both the upstream link and the downstream local hub.

  • latency (float, default: 0.01) – Polling interval (seconds) propagated to the downstream local hub.

  • local_host (str, default: "127.0.0.1") – Downstream bind host, used only when local_unixsocket is None.

  • local_port (int or None, optional) – Downstream TCP port. Ignored when a UNIX socket is used.

  • local_unixsocket (str or None, optional) – Downstream UNIX-socket address. When both this and local_port are None, a sanitized name derived from group_id is used.

Raises:

ValueError – If group_id is empty.

__init__(*, group_id, upstream_host, upstream_port, timeout=60.0, latency=0.01, local_host='127.0.0.1', local_port=None, local_unixsocket=None)[source]
Parameters:
  • group_id (str)

  • upstream_host (str)

  • upstream_port (int)

  • timeout (float)

  • latency (float)

  • local_host (str)

  • local_port (int | None)

  • local_unixsocket (str | None)

property local_endpoint: dict

Return the downstream socket endpoint local drivers should connect to.

Returns:

{"unixsocket": <name>} when a UNIX socket is configured, otherwise {"host": <host>, "port": <port>}.

Return type:

dict

run()[source]

Run the bridge loop until the hub sends STOP or disconnects.

Raises:

RuntimeError – If the upstream hub sends an unrecognized aggregate header.

Return type:

None

Notes

Connects upstream (with retry), sends HELLO, then services AGGINIT, AGGSTEP, and STOP frames in a loop. Upstream transport errors end the loop quietly; the downstream local hub is always stopped on exit.

start()[source]

Start the bridge loop in a daemon thread and return the thread handle.

Returns:

The running daemon thread. If a thread is already alive it is returned unchanged rather than starting a second one.

Return type:

threading.Thread

stop(wait=2.0)[source]

Stop the bridge loop and close the downstream local hub.

Parameters:

wait (float, default: 2.0) – Maximum time (seconds) to wait for the bridge thread to join after signalling it to stop.

Return type:

None

class maxwelllink.sockets.RemoteBridgeSpec[source]

Bases: object

One remote aggregate bridge entry produced by init_remote_bridges.

Variables:
  • idx (int) – Zero-based bridge index used by run_bridge_node().

  • group_id (str) – Aggregate group identifier transmitted upstream.

  • unixsocket (str) – Downstream UNIX-socket address local drivers should connect to.

  • n_molecules (int) – Number of molecules assigned to this bridge.

__init__(idx, group_id, unixsocket, n_molecules)
Parameters:
  • idx (int)

  • group_id (str)

  • unixsocket (str)

  • n_molecules (int)

Return type:

None

classmethod from_dict(payload)[source]

Build one bridge specification from JSON-decoded manifest data.

Parameters:

payload (Mapping) – Mapping carrying idx, group_id, unixsocket, and n_molecules entries, as written by to_dict().

Returns:

The reconstructed, type-coerced specification.

Return type:

RemoteBridgeSpec

Raises:

KeyError – If a required field is missing from payload.

group_id: str
idx: int
n_molecules: int
to_dict()[source]

Return a JSON-serializable bridge specification mapping.

Returns:

Mapping with the idx, group_id, unixsocket, and n_molecules fields coerced to plain JSON types.

Return type:

dict

unixsocket: str
class maxwelllink.sockets.SocketHub[source]

Bases: DummySocketHub

The concrete default socket hub used by MaxwellLink simulations.

All machinery is inherited unchanged from DummySocketHub; this subclass exists for naming symmetry with the rest of the package (every Dummy* base has a concrete counterpart) and is the class users instantiate:

from maxwelllink import SocketHub

hub = SocketHub(host="127.0.0.1", port=31415)
hub.wait_until_bound({0: {"molecule_id": 0}})
results = hub.step_barrier({0: {"efield_au": [0.0, 0.0, 1e-6]}})
hub.stop()

See DummySocketHub for the full method documentation and the subclassing contract.

__init__(host=None, port=31415, unixsocket=None, timeout=60000.0, latency=0.01)

Initialize the socket hub.

Parameters:
  • host (str or None, default: None) – Host address for AF_INET sockets. Ignored when using a UNIX socket.

  • port (int or None, default: 31415) – TCP port for AF_INET sockets. Ignored for UNIX sockets.

  • unixsocket (str or None, default: None) – Path (or name under /tmp/socketmxl_*) for a UNIX domain socket. When provided, host and port are ignored.

  • timeout (float, default: 60000.0) – Socket timeout (seconds) for client operations.

  • latency (float, default: 0.01) – Polling sleep (seconds) between hub sweeps; can be very small for local runs.

all_bound(molecule_ids, require_init=True)

Check if all given molecule IDs are bound (and optionally initialized).

Parameters:
  • molecule_ids (iterable of int) – Molecule IDs to check.

  • require_init (bool, default: True) – Also require that clients completed INIT.

Returns:

True if all are bound (and initialized if requested), else False.

Return type:

bool

graceful_shutdown(reason=None, wait=2.0)

Politely ask all connected drivers to exit and wait briefly for BYE.

Parameters:
  • reason (str or None, optional) – Optional reason to log for shutdown.

  • wait (float, default: 2.0) – Seconds to wait for clean replies.

register_molecule(molecule_id)

Reserve a slot for a given molecule ID (client may connect later).

Parameters:

molecule_id (int) – Molecule ID to register.

Raises:

ValueError – If the molecule ID is already registered.

Return type:

None

register_molecule_return_id()

Reserve a slot for a molecule and return an auto-assigned ID.

Returns:

The assigned unique molecule ID.

Return type:

int

step_barrier(requests, timeout=None)

Barrier step: dispatch fields and collect source amplitudes from all clients.

Coordinates sending fields, waiting for results, and jointly committing the results once every requested molecule is ready. A frozen barrier is reused if a disconnect occurs mid-step.

Parameters:
  • requests (dict[int, dict]) – Mapping from molecule ID to request dict with keys: - "efield_au" : array-like (3,) field vector in a.u. - "meta" : dict, optional metadata per send. - "init" : dict, optional INIT payload for first bind.

  • timeout (float, optional) – Maximum time (seconds) to wait for the barrier to complete. Defaults to the hub’s timeout setting.

Returns:

Mapping molid -> {"amp": ndarray(3,), "extra": bytes}. Returns {} when paused, on abort, or if the barrier is incomplete.

Return type:

dict[int, dict]

stop()

Stop accepting new connections, request clients to exit, and close sockets.

Also removes the UNIX socket path if one was created.

wait_until_bound(init_payloads, require_init=True, timeout=None)

Block until all requested molecule IDs are bound (and optionally initialized).

Parameters:
  • init_payloads (dict[int, dict]) – Mapping from molecule ID to INIT payload to use on bind.

  • require_init (bool, default: True) – Also require that clients completed INIT.

  • timeout (float or None, optional) – Maximum time to wait (seconds). When None (the default) this method waits indefinitely — the hub-wide self.timeout is not applied here.

Returns:

True if all requested IDs became bound within the time limit, else False.

Return type:

bool

class maxwelllink.sockets.SusceptibilitySocketHub[source]

Bases: _HubProcessProxy

Process-backed hub for Meep MXLSocketSusceptibility connections.

The hub starts immediately during construction and exposes the endpoint fields consumed by mp.MXLSocketSusceptibility(hub=hub). The actual server (_SusceptibilitySocketHubServer) runs in a child process; see _meep_hub_base.py for why and for the shared proxy machinery.

Parameters:
  • host (str or None, optional) – Bind host for the server. None uses the server default.

  • port (int or None, default: 31415) – Bind port. 0 requests an OS-chosen ephemeral port.

  • timeout (float, default: 60000.0) – Socket timeout in seconds passed to the server.

  • latency (float, default: 0.05) – Polling interval in seconds passed to the server.

  • unixsocket (str or None, optional) – Reserved; must be falsy (TCP only).

  • driver_count_file (str or None, default: "num_socket_molecule") – File that receives the total number of socket molecules required by Meep, written by the child server as a single integer after MXLINIT. Set to None to disable.

Variables:
  • host (str) – Resolved bind host of the running server.

  • port (int) – Resolved bind port of the running server.

  • address (str) – Alias of host.

  • rank_stats (dict[int, dict]) – Latest per-Meep-rank statistics drained from the child process.

Raises:
  • ValueError – If unixsocket is given.

  • RuntimeError – If the child server fails to start.

__init__(host=None, port=31415, timeout=60000.0, latency=0.05, unixsocket=None, driver_count_file='num_socket_molecule')[source]

Initialize the proxy-side state shared by every process-backed hub.

Concrete hubs validate their own arguments, call this, set any extra attributes, and then call _start_server_process(). Pre-setting the lifecycle attributes here keeps stop() and __del__ safe even when a subclass __init__ fails before the child is launched.

Parameters:
  • timeout (float) – Socket timeout (seconds) passed to the child server.

  • latency (float) – Polling interval (seconds) passed to the child server.

  • host (str | None)

  • port (int | None)

  • unixsocket (str | None)

  • driver_count_file (str | None)

lorentzian_conversion(frequency, sigma, resolution, *, gamma=0.0, dimensions=1, time_units_fs=0.1, mu0_au=187.0819866, orientation=0)

Convert a Meep Lorentzian susceptibility to SHO driver parameters.

The numerical mapping is lorentzian_to_sho_parameters(); this template adds the launch command from _driver_command_for() (targeting this hub’s transport), prints a short report on the MPI master, and merges any _conversion_extras() into the result.

Returns:

{"rescaling_factor", "driver_command", ...extras} where rescaling_factor is the symmetric bright-state coupling scale to pass to mp.MXLSocketSusceptibility(rescaling_factor=...).

Return type:

dict

Raises:

ValueError – If any argument is outside its documented valid range.

Parameters:
  • frequency (float)

  • sigma (float)

  • resolution (float)

  • gamma (float)

  • dimensions (int)

  • time_units_fs (float)

  • mu0_au (float)

  • orientation (int)

property rank_stats: dict[int, dict]

Latest per-Meep-rank statistics from the running server.

Returns:

Mapping from rank to its stats row (molecule_count, steps, requests, peer, …). Empty on non-master ranks.

Return type:

dict[int, dict]

stop()

Stop the hub and tear down the child server process.

Idempotent and safe on non-master ranks. Signals the child via the stop event, joins it, and falls back to terminate() if it does not exit; a final stats drain captures any closing counters.

Return type:

None

maxwelllink.sockets.am_master()[source]

Return True if this process is the MPI master rank (rank 0), otherwise False.

Notes

Attempts to import mpi4py and query COMM_WORLD. If unavailable, returns True by treating the single process as rank 0.

maxwelllink.sockets.get_available_host_port(localhost=True, save_to_file=None)[source]

Ask the OS for an available localhost TCP port.

Parameters:
  • localhost (bool, default: True) – If True, bind to the localhost interface (“127.0.0.1”). If False, bind to all interfaces (“0.0.0.0”).

  • save_to_file (str or None, default: None) – If provided, save the selected host and port to the given file with filename provided by save_to_file. The first line contains the host, and the second line contains the port.

Returns:

(host, port) pair, e.g., ("127.0.0.1", 34567).

Return type:

tuple

maxwelllink.sockets.mpi_bcast_from_master(value)[source]

Broadcast a Python value from the master rank to all ranks via MPI.

Parameters:

value (any) – The value to broadcast.

Returns:

The broadcast value (unchanged when MPI is unavailable).

Return type:

any

maxwelllink.sockets.run_bridge_node(info='aggregation.json', *, idx=0)[source]

Run one bridge node from a manifest written by init_remote_bridges.

Parameters:
  • info (str or path-like, default: "aggregation.json") – JSON manifest written by AggregatedSocketHub.init_remote_bridges().

  • idx (int, default: 0) – Zero-based bridge index identifying which bridge entry in info this node should start.

Raises:

IndexError – If no bridge entry in info has the requested idx.

Return type:

None

Notes

The call blocks until the bridge thread exits or a KeyboardInterrupt is received, after which the bridge is stopped on a best-effort basis.

Submodules