nexus-queue 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/CHANGELOG.md +7 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/PKG-INFO +1 -1
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/config.py +15 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/lifecycle.py +26 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/pyproject.toml +1 -1
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/.gitignore +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/.python-version +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/README.md +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/__init__.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/app.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/broker.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/delayed.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/envelope.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/exceptions.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/handlers.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/kicker.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/middleware/__init__.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/middleware/metrics.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/middleware/retry_dlq.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/naming.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/pipeline.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/ports.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/publisher.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/py.typed +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/nexus_queue/tracing.py +0 -0
- {nexus_queue-0.1.1 → nexus_queue-0.1.2}/tests/test_integration.py +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.2](https://github.com/Zetesis-Labs/PayloadAgents/compare/nexus-queue-v0.1.1...nexus-queue-v0.1.2) (2026-06-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **nexus-queue:** serve worker Prometheus metrics over HTTP ([#100](https://github.com/Zetesis-Labs/PayloadAgents/issues/100)) ([cb5af8a](https://github.com/Zetesis-Labs/PayloadAgents/commit/cb5af8aaa944681358175e425ef88b2ee9e282be))
|
|
9
|
+
|
|
3
10
|
## [0.1.1](https://github.com/Zetesis-Labs/PayloadAgents/compare/nexus-queue-v0.1.0...nexus-queue-v0.1.1) (2026-06-17)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexus-queue
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Nexus-Queue — portable taskiq + Redis Streams worker runtime: namespaced streams, versioned envelope, ports-and-adapters, retry/DLQ/idempotency/tracing/metrics middleware.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Zetesis-Labs/PayloadAgents
|
|
6
6
|
Project-URL: Repository, https://github.com/Zetesis-Labs/PayloadAgents
|
|
@@ -69,6 +69,21 @@ class RuntimeConfig(BaseModel):
|
|
|
69
69
|
description="Approx MAXLEN for the dead-letter stream; 0 = unbounded.",
|
|
70
70
|
)
|
|
71
71
|
|
|
72
|
+
# ── Observability ──────────────────────────────────────────────────────
|
|
73
|
+
metrics_port: int | None = Field(
|
|
74
|
+
default=None,
|
|
75
|
+
gt=0,
|
|
76
|
+
lt=65_536,
|
|
77
|
+
description=(
|
|
78
|
+
"If set, the worker serves Prometheus metrics on this port via an "
|
|
79
|
+
"in-process HTTP server (scrape target for a ServiceMonitor). The "
|
|
80
|
+
"taskiq worker has no HTTP server otherwise, so its consume counters "
|
|
81
|
+
"are invisible without this. Run the worker single-process "
|
|
82
|
+
"(taskiq --workers 1) and scale by pods, or the port will collide. "
|
|
83
|
+
"None disables it."
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
|
|
72
87
|
# ── Logging ────────────────────────────────────────────────────────────
|
|
73
88
|
log_level: str = Field(default="INFO")
|
|
74
89
|
|
|
@@ -11,12 +11,15 @@ import logging
|
|
|
11
11
|
|
|
12
12
|
import redis.asyncio as aioredis
|
|
13
13
|
import structlog
|
|
14
|
+
from prometheus_client import start_http_server
|
|
14
15
|
from taskiq import AsyncBroker, TaskiqEvents, TaskiqState
|
|
15
16
|
|
|
16
17
|
from nexus_queue.config import RuntimeConfig
|
|
17
18
|
from nexus_queue.delayed import DelayedRetryPoller
|
|
18
19
|
from nexus_queue.naming import idempotency_redis_key
|
|
19
20
|
|
|
21
|
+
logger = structlog.get_logger("nexus_queue.lifecycle")
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
class IdempotencyStore:
|
|
22
25
|
"""Redis mark-done dedup keyed by the message's ``nq_idem`` label.
|
|
@@ -71,6 +74,28 @@ def configure_logging(config: RuntimeConfig) -> None:
|
|
|
71
74
|
)
|
|
72
75
|
|
|
73
76
|
|
|
77
|
+
def _start_metrics_server(config: RuntimeConfig) -> None:
|
|
78
|
+
"""Serve the Prometheus registry over HTTP from the worker process.
|
|
79
|
+
|
|
80
|
+
The consume counters/histogram live in this process; the kicker is a
|
|
81
|
+
separate pod with its own registry, so without this the worker's metrics
|
|
82
|
+
have no scrape endpoint. Best-effort: a metrics-server failure (e.g. a
|
|
83
|
+
port collision when mistakenly run multi-process) must never take the
|
|
84
|
+
worker down."""
|
|
85
|
+
if config.metrics_port is None:
|
|
86
|
+
return
|
|
87
|
+
try:
|
|
88
|
+
start_http_server(config.metrics_port)
|
|
89
|
+
logger.info("metrics-server-started", port=config.metrics_port)
|
|
90
|
+
except OSError as exc:
|
|
91
|
+
logger.warning(
|
|
92
|
+
"metrics-server-failed",
|
|
93
|
+
port=config.metrics_port,
|
|
94
|
+
error=str(exc),
|
|
95
|
+
hint="run the worker single-process (taskiq --workers 1)",
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
74
99
|
def register_lifecycle(
|
|
75
100
|
broker: AsyncBroker,
|
|
76
101
|
config: RuntimeConfig,
|
|
@@ -89,6 +114,7 @@ def register_lifecycle(
|
|
|
89
114
|
async def _startup(state: TaskiqState) -> None: # pyright: ignore[reportUnusedFunction]
|
|
90
115
|
state.nexus_config = config
|
|
91
116
|
state.nexus_adapters = adapters
|
|
117
|
+
_start_metrics_server(config)
|
|
92
118
|
store = IdempotencyStore(config)
|
|
93
119
|
await store.startup()
|
|
94
120
|
state.nexus_idempotency = store
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nexus-queue"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "Nexus-Queue — portable taskiq + Redis Streams worker runtime: namespaced streams, versioned envelope, ports-and-adapters, retry/DLQ/idempotency/tracing/metrics middleware."
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|