The goal of Phase 1 – Translation was to recreate the core behavior of GoQueue and SpringQueue (base) in a Python environment without prematurely adopting framework-specific abstractions. This phase intentionally prioritized semantic equivalence and runtime correctness over idiomatic Python or FastAPI usage. (That would be the next Phase).
In other words, Phase 1 answers the question:
“If I strip away framework magic and write the system explicitly, do I truly understand how it works?”
Only once that answer was “yes” would refactoring and framework integration be justified.
PyQueue does not map cleanly to only one predecessor:
- GoQueue influenced runtime structure and explicit wiring
- SpringQueue influenced concurrency model and service design
This hybrid approach was deliberate. It stands in contrast to SpringQueue, which began as a direct translation of GoQueue into a Java-SpringBoot context, later refactored to be idiomatically Java and Spring. (This was only natural as SpringQueue was only preceded by GoQueue, and lessons learned there can be applied to PyQueue for efficiency).
GoQueue served as the conceptual baseline for:
- Explicit lifecycle management
- Manual instantiation of core components
- Clear visibility into how work enters and flows through the system
This influence is most visible in main.py, which closely mirrors GoQueue’s main.go:
- The Queue is instantiated explicitly
- Test tasks are manually enqueued
- The process is kept alive intentionally
- Shutdown behavior is controlled manually
This explicit bootstrap phase ensured that PyQueue’s runtime behavior was understood before layering in FastAPI.
SpringQueue influenced how concurrency is expressed in PyQueue.
Although Go uses goroutines and channels as first-class language features, Python—like Java—expects concurrency to be delegated to the runtime via executors and thread pools. Because of this:
queue.pyresemblesQueueService.javamore thanqueue.go- The Queue is treated as a coordination service, not a data structure
ThreadPoolExecutoris the natural Python analogue to Java’sExecutorService
This alignment avoided forcing Go-style concurrency patterns into Python, which would have been unidiomatic and misleading in a production context.
One of the most important lessons of Phase 1 emerged around Worker execution semantics.
In SpringQueue:
WorkerimplementsRunnableExecutorService.submit(worker)implicitly callsrun()- The execution contract is interface-based and implicit
Python’s ThreadPoolExecutor:
- Accepts explicit callables only
- Does not perform interface lookup
- Does not infer execution entrypoints
This surfaced early mistakes such as:
- Attempting to submit
task.execute - Defining
run(task)instead ofrun()
The correct translation was to:
- Treat
Workeras a stateful execution unit - Give it a zero-argument
run()method - Submit the bound method directly:
executor.submit(worker.run)
This preserved SpringQueue’s clean separation of data (Task) and behavior (Worker) while adapting properly to Python’s execution model.
This phase revealed an important structural truth:
Python without a DI container behaves far more like Go than Spring.
In SpringQueue:
- Component scanning instantiates services
- Dependency injection wires references
- Lifecycle hooks manage startup and shutdown
- The application launcher is intentionally minimal
In PyQueue (Phase 1):
- There is no framework-level container
- No automatic wiring
- No implicit lifecycle
- Everything must be created and coordinated manually
As a result, main.py temporarily acts as the system bootstrapper, just like GoQueue’s main.go.
Even though the project was initialized as a FastAPI application, FastAPI is intentionally ignored during this phase so that:
- The executor model can be validated in isolation
- Worker behavior can be observed directly
- Framework abstractions do not mask design flaws
This separation ensures that FastAPI is later added as a producer surface, not as a hidden driver of system behavior.
Unlike Go’s net/http or Spring’s controllers, FastAPI provides:
- Lifecycle hooks
- Background task helpers
- Async execution primitives
- Dependency injection features
Using these too early would have:
- Obscured concurrency semantics
- Hidden lifecycle responsibilities
- Made debugging harder during translation
Phase 1 therefore treated FastAPI as present but inactive:
- The app exists
- Routes exist
- But they do not yet participate in system control
This differs slightly from GoQueue and SpringQueue, where producers were set up immediately, but the difference is intentional: FastAPI is more opinionated and powerful, and deserves to be integrated only once the core system is stable.
- Core task lifecycle
- Executor-based concurrency
- Retry behavior
- Explicit wiring and ownership
- Runtime verification via bootstrap execution
- Async/await
- FastAPI background tasks
- asyncio primitives
- Idiomatic Python refactors (
@dataclass, context managers, etc.)
Those belong to Phase 2 – Refactoring & Integration.
SpringQueue worked largely because Spring handled:
- Lazy wiring
- Circular dependencies
- Lifecycle management
When translating to Python, those hidden assumptions surfaced immediately and had to be addressed explicitly.
In Spring:
- Circular references are resolved post-scan
@Lazyand DI handle cycles safely
In Python:
- Imports are executed eagerly
- Circular imports fail immediately
This forced:
- Deferred imports
- Explicit dependency passing
- Cleaner module boundaries
This again aligned PyQueue more closely with GoQueue’s explicit wiring model.
While Python and Java both rely on executors rather than language-level concurrency primitives, Python:
- Is more explicit
- Less interface-driven
- Less framework-assisted by default
Bridging this gap required careful translation rather than direct imitation.
Phase 1 was considered complete when:
python main.pycould be run- Tasks were enqueued manually
- Workers executed concurrently
- Retries behaved correctly
- The process lifecycle was fully understood and controlled
With that achieved (on 2026-01-29), PyQueue would be ready for Phase 2: FastAPI Integration & Idiomatic Refactoring.
NOTE: The explicit bookmark "end" of Phase 1 (the GitHub commit) should be saved somewhere for future architecture-related documentation. (I did a terrible job of keeping a record for SpringQueuePro and need to ammend that for this project).