Skip to main content

An embedded, crash-resilient, persistent queue engine for Python.

Project description

EQueue

Build Tests License: MIT

Persistent, crash-safe job queue for Python. No broker. No daemon. Just disk.

Jobs survive process restarts. Workers run as threads or separate processes on the same machine. Powered by LMDB, a memory-mapped database that writes atomically and recovers instantly after a crash.


Install

Not published yet.


Usage

Basic

from equeue import Queue

with Queue("./myqueue") as q:
    q.put({"task": "send_email", "to": "user@example.com"})

    record = q.get(timeout=5.0)
    try:
        send(record.payload)
        record.ack()       # job done
    except Exception:
        record.nack()      # re-queue, or mark FAILED after too many retries

Context manager (auto ack / nack)

with Queue("./myqueue") as q:
    with q.processing(timeout=5.0) as record:
        process(record.payload)
    # ack() on success, nack() on any exception

Async

from equeue import AsyncQueue

async with AsyncQueue("./myqueue") as q:
    await q.put({"task": "resize_image"})

    async with q.processing() as record:
        await handle(record.payload)

The Record

get() returns a Record. Completion always goes through the record, never through a bare job ID. This prevents one worker from accidentally finishing a job held by another.

Field Meaning
payload Job data passed to put()
job_id Stable integer ID, useful for logs
retries How many times this job was nacked
enqueued_at Unix timestamp from put()

Configuration

q = Queue(
    "./myqueue",
    lease_time=30.0,        # seconds before an idle job can be re-queued
    max_retries=3,          # nacks before FAILED (0 = one attempt only)
    map_size=2**30,         # LMDB virtual size in bytes (default 1 GiB)
    sync=False,             # True = safer, slower (fsync every write)
    do_recover=True,        # background thread re-queues expired jobs
    recover_interval=15.0,
    do_vacuum=True,         # background thread removes old DONE jobs
    vacuum_interval=300.0,
)

Statistics

q.stats()
# {
#     "pending":   4,   # waiting for a worker
#     "running":   1,   # claimed by a worker
#     "done":    120,   # finished successfully
#     "failed":    2,   # exceeded retry limit
#     "total":   127,   # ever enqueued; never decreases
# }

Job lifecycle

PENDING  -->  RUNNING  -->  DONE  -->  (vacuumed)
                  |
                  +--> PENDING   nack() with retries left, or lease expired
                  |
                  +--> FAILED    nack() with no retries left (kept on disk)

Exceptions

Exception When
QueueEmpty get(timeout=...) found no job in time
QueueClosed Operation on a closed queue
QueueCorrupted Wrong claim token, double ack, or broken disk state

Notes

  • At-least-once delivery. A job can run more than once if a worker crashes or its lease expires. Make handlers idempotent.
  • Payload types. Values must be msgpack-serializable: dicts, lists, strings, numbers, bytes, None.
  • map_size is not disk usage. It is virtual address space. Disk grows as data is written.
  • Not a distributed broker. EQueue is for one machine. It does not replace Redis or Kafka.

Docs

uv run pytest              # all tests
uv run pytest -m contract  # RFC contract tests only

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lmdb_queue-0.1.0.tar.gz (116.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lmdb_queue-0.1.0-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file lmdb_queue-0.1.0.tar.gz.

File metadata

  • Download URL: lmdb_queue-0.1.0.tar.gz
  • Upload date:
  • Size: 116.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lmdb_queue-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c33755c664884fecb4e175f2079610efdfeff9c0ffd7cad8bcb17a816ea099fe
MD5 1ebc044f9359cb7cff754ad625a462ab
BLAKE2b-256 b2d0c3235b466e42b202e24c9d89ff0c8fcdb826cc3a5f94c87169ae961c5f31

See more details on using hashes here.

Provenance

The following attestation bundles were made for lmdb_queue-0.1.0.tar.gz:

Publisher: publish.yml on PabloSanchi/equeue

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lmdb_queue-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lmdb_queue-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lmdb_queue-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55583d32e01725562b7ff4a3b471715b4e0f75641639ea13ac1336baeddf4696
MD5 df8d3b3ae2ef67bfcb0390fa25a24c1f
BLAKE2b-256 d2f63a0abea09ff3e281a2b69ac590f16406e2db686008d6e1c71d511d8c9acf

See more details on using hashes here.

Provenance

The following attestation bundles were made for lmdb_queue-0.1.0-py3-none-any.whl:

Publisher: publish.yml on PabloSanchi/equeue

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page