Skip to main content

semqueue

Queues that bound in-flight items (waiting + being processed), not just waiting items

  • SyncQueue - drop-in replacement for queue.Queue
  • AsyncQueue - drop-in replacement for asyncio.Queue
  • Both support Queue, PriorityQueue, or LifoQueue as the inner queue via queue_cls

Why

Backpressure. When producers are faster than consumers and downstream processing is expensive (memory, connections, rate limits), you want to bound the total work in flight, not just the queue depth

The problem with queue.Queue / asyncio.Queue

  • maxsize=N only bounds items waiting in the queue
  • consumers pull items and process them concurrently
  • total items in the system (queued + being processed) can exceed N

semqueue fixes this by using a Semaphore:

  • acquire on put, release on task_done
  • total in-flight (queued + being processed) never exceeds maxsize

Installation

pip install semqueue

Usage - SyncQueue

Basic

from semqueue import SyncQueue

q = SyncQueue(maxsize=4)

# Use PriorityQueue or LifoQueue as the inner queue
from queue import PriorityQueue

q = SyncQueue(maxsize=4, queue_cls=PriorityQueue)

Producer / consumer

import threading
from semqueue import SyncQueue

q = SyncQueue(maxsize=4)


def producer():
    for i in range(100):
        q.put(i)  # blocks if 4 items are in-flight


def consumer():
    while True:
        item = q.get()
        process(item)
        q.task_done()  # frees a slot


threading.Thread(target=producer).start()
threading.Thread(target=consumer).start()

Timeout and non-blocking puts

from semqueue import SyncQueue, Full

q = SyncQueue(maxsize=2)
q.put("a")
q.put("b")

try:
    q.put("c", block=True, timeout=0.5)
except Full:
    print("in-flight limit reached")

try:
    q.put_nowait("c")
except Full:
    print("would exceed in-flight limit")

Full is queue.Full re-exported, so existing code works unchanged.

Shutdown

from semqueue import SyncQueue
from queue import ShutDown

q = SyncQueue(maxsize=4)

q.shutdown()  # graceful: stops new puts, consumers drain
q.shutdown(immediate=True)  # immediate: drains queue, unblocks join()

q.put("x")  # raises ShutDown
q.get()  # raises ShutDown if empty

Usage - AsyncQueue

Basic

from semqueue import AsyncQueue

q = AsyncQueue(maxsize=4)

# Use PriorityQueue or LifoQueue as the inner queue
from asyncio import PriorityQueue

q = AsyncQueue(maxsize=4, queue_cls=PriorityQueue)

Producer / consumer

import asyncio
from semqueue import AsyncQueue

q = AsyncQueue(maxsize=4)


async def producer():
    for i in range(100):
        await q.put(i)  # blocks if 4 items are in-flight


async def consumer():
    while True:
        item = await q.get()
        await process(item)
        q.task_done()  # frees a slot


async def main():
    await asyncio.gather(producer(), consumer())


asyncio.run(main())

Non-blocking puts

from semqueue import AsyncQueue, QueueFull

q = AsyncQueue(maxsize=2)
await q.put("a")
await q.put("b")

try:
    q.put_nowait("c")
except QueueFull:
    print("would exceed in-flight limit")

QueueFull is asyncio.QueueFull re-exported, so existing code works unchanged.

Shutdown

from semqueue import AsyncQueue
from asyncio import QueueShutDown

q = AsyncQueue(maxsize=4)

q.shutdown()  # graceful: stops new puts, consumers drain
q.shutdown(immediate=True)  # immediate: drains queue, unblocks join()

await q.put("x")  # raises QueueShutDown
await q.get()  # raises QueueShutDown if empty

License

MIT

Download files

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

Source Distribution

semqueue-0.1.0.tar.gz (4.1 kB view details)

Uploaded Source

Built Distribution

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

semqueue-0.1.0-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: semqueue-0.1.0.tar.gz
  • Upload date:
  • Size: 4.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for semqueue-0.1.0.tar.gz
Algorithm Hash digest
SHA256 aa2e8c6a0a4da65d4ce79a0ae9be725c2ecc17325a599af985c799eabcd22081
MD5 5820110d0429d2037920516c210b14f3
BLAKE2b-256 7e9a45a320c58bd0ed5e705ba79b40897ffcf48ffc754182db8e78c26d5f3852

See more details on using hashes here.

File details

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

File metadata

  • Download URL: semqueue-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for semqueue-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 48bb8d1d17cdcddb132217cade0a1dbba45973d4cabbcdc8fb7d5f49ca1159de
MD5 9f55a60dd5bef37ae2ca974723fdd2d2
BLAKE2b-256 cf88b1de6723996023e769fc099f706f4ac2113c5f029c851b62a29cfe339e35

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page