Skip to content

Windows compatibility

Only the local broker cares about the OS: it starts its server (fp-brokerd) as a child process. memory, postgres and rabbitmq behave the same everywhere.

What differs

src/broker/local.py picks the multiprocessing start method by platform:

_IS_WINDOWS = platform.system() == "Windows"
_MP_CONTEXT = get_context("spawn" if _IS_WINDOWS else "fork")

and LocalBroker.setup() starts the server with _MP_CONTEXT.Process(target=_serve_manager, args=(address, authkey, owner_pid), name="fp-brokerd").

Linux (fork) Windows (spawn)
Server start fast, inherits the parent's memory slower, re-imports the main module
Main-module guard needed no yes

Requirements on Windows

1. Guard the entry point. spawn re-imports the main module in the child; without the guard the child starts the app again and Python raises "An attempt has been made to start a new process before the current process has finished its bootstrapping phase".

# main.py
from fastapi import FastAPI
from fastpluggy.fastpluggy import FastPluggy
from fastpluggy_plugin.tasks_worker import TaskWorker

app = FastAPI()

if __name__ == "__main__":
    import uvicorn

    TaskWorker.setup_broker()          # starts fp-brokerd here, under the guard
    FastPluggy(app)
    uvicorn.run(app, host="127.0.0.1", port=8000)

2. Frozen executables (PyInstaller and similar) also need multiprocessing.freeze_support() as the first line under the guard.

3. Define tasks at module level. A task is sent as "<module>:<qualname>" and re-imported by the worker (core/utils.py:path_to_func). A function defined inside another function has <locals> in its qualname and cannot be resolved. This applies on every OS, not just Windows.

Troubleshooting

  • BrokenPipeError / EOFError when connecting: fp-brokerd did not start or died. Call TaskWorker.setup_broker() before any task operation and check that nothing blocks 127.0.0.1:50050 (or the address in BROKER_DSN).
  • "Address ... is in use but nothing answered": a wedged process holds the port. Kill it; see broker/technical.md.
  • Check the server from Python:
from fastpluggy_plugin.tasks_worker.broker.local import LocalBroker

proc = LocalBroker._server_proc   # set only in the process that spawned fp-brokerd
print("fp-brokerd alive:", bool(proc and proc.is_alive()))

References