Raxx · internal docs

internal · gated ↑ index

ADR-0066 — Queue v1: Co-location as Flask Blueprint Mounted in Raptor

Date: 2026-05-09 UTC Status: Accepted Deciders: software-architect Context: docs/architecture/queue/design.md §Queue Codebase Location


Context

Given ADR-0065 (strangler-fig), Queue must run within the same Heroku dyno as Raptor in v1. There are two sub-options:

Option A — Separate process on same dyno: Queue runs as a separate Flask process on a different port (e.g., 5002). Raptor calls localhost:5002 for identity operations. Service-to-service auth is enforced even locally.

Option B — Flask Blueprint mounted in Raptor's app factory: Queue is a Flask blueprint (or set of blueprints) registered in backend_v2/api/__init__.py at /api/v1/. Queue's code still lives in queue/ (separate module directory), but is imported and mounted by Raptor's factory.


Decision

Option B — Flask Blueprint mounted in Raptor's app factory.

Queue's blueprints are registered under the /api/v1/ prefix in Raptor's app factory behind FLAG_QUEUE_V1. Queue's module directory (queue/) is a sibling to backend_v2/ in the repo. Raptor imports Queue at startup:

# backend_v2/api/__init__.py (app factory)
if feature_flags.get("FLAG_QUEUE_V1"):
    from queue.api.app import create_queue_blueprints
    for bp in create_queue_blueprints():
        app.register_blueprint(bp, url_prefix="/api/v1")

Consequences

Positive: - Single process, single port — no added latency for Raptor → Queue calls in Phase 1. - Same Gunicorn worker pool handles both Raptor and Queue requests. Simpler Procfile. - Module boundary is enforced by directory separation (queue/ vs backend_v2/). CI can lint that backend_v2/ does not import from queue/api/ internal modules (only through the public contract). - Phase 4 extraction is clean: Queue's app.py already has a standalone factory that can run independently; the Raptor import is removed, and Queue gets its own Procfile.

Negative: - A crash in Queue's request handler can propagate to the shared process. Mitigated by Flask error handlers on each blueprint. - Raptor and Queue share the same in-process state (e.g., Flask current_app). Queue must use namespaced config keys to avoid collisions.


Alternatives Considered

Option A (separate process): Adds networking overhead even locally. Complicates the Procfile. Service-to-service auth must be set up before Phase 1 endpoints are usable. Deferred to Phase 4 when Queue runs as a true standalone Heroku app.