taskiq-postgresql version
0.4.0
Python version
Python 3.14
PostgreSQL driver
asyncpg
PostgreSQL version
Debian 18.1-1.pgdg13+2
Summary
taskiq-postgresql crashes when a task has a float delay, because the broker expects the delay label to be an int.
However, both:
SmartRetryMiddleware
- and explicit task definitions like
@broker.task(delay=2.5)
produce float delays, which are serialized as strings (e.g., "2.5") before being stored.
During processing, taskiq-postgresql attempts to parse this value using:
|
delay_value = message.labels.get("delay") |
|
if delay_value is not None: |
|
delay_seconds = int(delay_value) |
This fails for any non-integer delay and causes the worker to crash.
Steps to Reproduce
- Configure a PostgreSQL broker.
- Register a task with a float delay label (
delay=2.5)
- Execute the task
Minimal code example
import asyncio
from taskiq_postgresql import PostgresqlBroker, PostgresqlResultBackend
from taskiq.api import run_receiver_task
async def main() -> None:
backend = PostgresqlResultBackend(
dsn='dsn',
run_migrations=True,
)
broker = PostgresqlBroker(
dsn='dsn',
run_migrations=True,
).with_result_backend(backend)
await broker.startup()
worker_task = asyncio.create_task(run_receiver_task(broker))
async def handler(x):
print("A", x)
dyn_task = broker.register_task(
handler,
task_name="dyn_task",
delay=2.5,
)
await dyn_task.kiq(x=4)
await asyncio.sleep(5)
worker_task.cancel()
try:
await worker_task
except asyncio.CancelledError:
print("Worker successfully exited.")
await broker.shutdown()
if __name__ == "__main__":
asyncio.run(main())
Actual Behavior
Worker fails and freezes with:
delay_seconds = int(delay_value)
ValueError: invalid literal for int() with base 10: '2.5'
because the label value arrives as a serialized string "2.5".
Expected Behavior
- Delay labels should be properly deserialized before parsing.
- Float delays (commonly produced by SmartRetryMiddleware) should be supported.
- Worker should not crash.
Root Cause
-
taskiq serializes label values, turning 2.5 into "2.5".
-
taskiq-postgresql does not deserialize the label before using it.
-
The broker assumes delay is always an integer, but this is not true when:
- using
@broker.task(delay=2.5)
- using
SmartRetryMiddleware, which computes delays as floats (e.g., exponential backoff)
This causes int("2.5") to raise a ValueError.
Proposed Fix
Deserialize the label value by parsing it like its done in taskiq-aio-pika:
https://github.com/taskiq-python/taskiq-aio-pika/blob/ed4a0f9904466d175b515ff4a1efbc6be5c21da9/taskiq_aio_pika/broker.py#L262
Or simply change int to float like so:
delay_value = message.labels.get("delay")
if delay_value is not None:
delay_seconds = float(delay_value)
Additionally, _schedule_notification will need its delay_seconds parameter changed from int to float.
taskiq-postgresql version
0.4.0
Python version
Python 3.14
PostgreSQL driver
asyncpg
PostgreSQL version
Debian 18.1-1.pgdg13+2
Summary
taskiq-postgresqlcrashes when a task has a float delay, because the broker expects the delay label to be anint.However, both:
SmartRetryMiddleware@broker.task(delay=2.5)produce float delays, which are serialized as strings (e.g.,
"2.5") before being stored.During processing,
taskiq-postgresqlattempts to parse this value using:taskiq-postgresql/taskiq_postgresql/broker.py
Lines 183 to 185 in 0daf18d
This fails for any non-integer delay and causes the worker to crash.
Steps to Reproduce
delay=2.5)Minimal code example
Actual Behavior
Worker fails and freezes with:
because the label value arrives as a serialized string
"2.5".Expected Behavior
Root Cause
taskiqserializes label values, turning2.5into"2.5".taskiq-postgresqldoes not deserialize the label before using it.The broker assumes delay is always an integer, but this is not true when:
@broker.task(delay=2.5)SmartRetryMiddleware, which computes delays as floats (e.g., exponential backoff)This causes
int("2.5")to raise aValueError.Proposed Fix
Deserialize the label value by parsing it like its done in
taskiq-aio-pika:https://github.com/taskiq-python/taskiq-aio-pika/blob/ed4a0f9904466d175b515ff4a1efbc6be5c21da9/taskiq_aio_pika/broker.py#L262
Or simply change int to float like so:
Additionally,
_schedule_notificationwill need itsdelay_secondsparameter changed frominttofloat.