Skip to content

Runtime

Runtime is the server behind a dashboard. Dashboard owns one, and dachshund.init() and dachshund.shutdown() start and stop it.

dachshund.runtime.boot.Runtime

Runtime(create_app, *, host=DEFAULT_HOST, port=DEFAULT_PORT)

The dashboard server, running inside the host process.

It runs on a background thread with its own event loop and never touches the host's loop. Each start() builds a fresh application from the factory.

Under a multi-worker server, only one worker can bind the port. The others keep retrying in the background and take over if it stops, see is_serving.

Source code in dachshund/runtime/boot.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(
    self,
    create_app: AppFactory,
    *,
    host: str = DEFAULT_HOST,
    port: int = DEFAULT_PORT,
) -> None:
    self.create_app = create_app
    self.host = host
    self.requested_port = port

    self._port: int | None = None
    self._pid: int | None = None
    self._thread: threading.Thread | None = None
    self._loop: asyncio.AbstractEventLoop | None = None
    self._shutdown: asyncio.Event | None = None
    self._ready = threading.Event()
    self._error: BaseException | None = None

create_app instance-attribute

create_app = create_app

host instance-attribute

host = host

requested_port instance-attribute

requested_port = port

port property

port

The port the dashboard is bound to.

url property

url

The address the dashboard is reachable at.

is_running property

is_running

Whether the runtime thread is alive.

is_serving property

is_serving

Whether this worker currently holds the dashboard port.

start

start()

Start the runtime and wait for it to accept connections.

Source code in dachshund/runtime/boot.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def start(self) -> None:
    """Start the runtime and wait for it to accept connections."""
    if self.is_running:
        return

    self._forget()
    self._ready.clear()
    self._error = None
    self._pid = os.getpid()

    self._thread = threading.Thread(
        target=self._run,
        name=RUNTIME_THREAD,
        daemon=True,
    )
    self._thread.start()

    if not self._ready.wait(STARTUP_TIMEOUT):
        self.stop()
        raise RuntimeError(
            f"The runtime did not start within {STARTUP_TIMEOUT} seconds."
        )

    if self._error is not None:
        self.stop()
        raise self._error

stop

stop()

Stop the runtime and wait for its thread to exit.

Source code in dachshund/runtime/boot.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def stop(self) -> None:
    """Stop the runtime and wait for its thread to exit."""
    if self._pid is not None and self._pid != os.getpid():
        self._forget()
        return

    loop, shutdown, thread = self._loop, self._shutdown, self._thread

    if loop is not None and shutdown is not None:
        try:
            loop.call_soon_threadsafe(shutdown.set)
        except RuntimeError:
            pass

    if thread is not None:
        thread.join(SHUTDOWN_TIMEOUT)

        if thread.is_alive():
            logger.warning(
                "The runtime thread is still running %s seconds after being "
                "asked to stop.",
                SHUTDOWN_TIMEOUT,
            )
            return

    self._forget()