simvx.core.background

BackgroundSlot: run one slow call off the frame thread and poll for its result.

The frame loop is synchronous, so anything slow (a network request, a directory walk, an expensive solve) freezes the game if it runs inline. A BackgroundSlot owns one worker thread and at most one in-flight call. The frame thread only ever calls :meth:submit (returns immediately) and :meth:poll (non-blocking; hands back a finished result or None).

Policy:

  • Coalesce: at most one call in flight. :meth:submit returns False and does nothing while one is pending, so a caller that submits every frame still issues one call at a time and never builds a backlog of stale work.

  • Graceful degrade: a raising call is logged with its specific exception and

    meth:

    poll returns None, so the caller keeps its last good value. There is no bare except swallowing the cause.

  • Teardown: :meth:close is idempotent and joins the worker. The worker is a daemon thread, so a crashed game still exits.

::

slot: BackgroundSlot[Reply] = BackgroundSlot()
...
if not slot.pending:
    slot.submit(lambda: expensive(snapshot))
result = slot.poll()
if result is not None:
    self.last_good = result

Module Contents

Classes

BackgroundSlot

Runs one callable off the frame thread at a time. Poll for the result.

Data

log

API

simvx.core.background.log

‘getLogger(…)’

class simvx.core.background.BackgroundSlot(*, thread_name: str = 'simvx-background')[source]

Runs one callable off the frame thread at a time. Poll for the result.

Initialization

property pending: bool[source]

True while a submitted call is still running, so callers can gate cadence.

submit(fn: collections.abc.Callable[[], T]) → bool[source]

Run fn on the worker thread, coalescing to one in-flight call.

Returns True if accepted, False if dropped because a call is already in flight or the slot is closed. A dropped fn is never invoked.

poll() → T | None[source]

Return a freshly finished result, or None if nothing finished or it failed.

Non-blocking: never waits on the worker. On success the slot is cleared and the value handed back. On failure the exception is logged and None is returned, so the caller retains its last good value. While a call is still running, or nothing has been submitted, returns None.

cancel() → None[source]

Drop the in-flight call without shutting the worker down.

A call the worker has already started runs to completion; its result is discarded rather than handed to the next :meth:poll.

close() → None[source]

Drop pending work, stop the worker and join it (idempotent).