+Compare immediate rejection when the queue is full. This Python 3 example uses put_nowait: instead of waiting to admit the second item, it receives QueueFull and reports that the item was not accepted. The final read returns first, the item already in the queue. put_nowait contract.
import asyncio
queue = asyncio.Queue(maxsize=1)
queue.put_nowait("first")
try:
queue.put_nowait("second")
except asyncio.QueueFull:
print("second: not accepted")
print(queue.get_nowait()) # first
Using await put with the same one-slot capacity waits instead. Run this example on Python 3.11 or later. The put_started event establishes when the second insertion starts; while the first item remains in the queue, the second put has not completed.
import asyncio
async def main():
queue = asyncio.Queue(maxsize=1)
await queue.put("first")
put_started = asyncio.Event()
async def put_second():
put_started.set()
await queue.put("second")
async with asyncio.TaskGroup() as group:
pending = group.create_task(put_second())
await put_started.wait()
print(pending.done()) # False
first = await queue.get()
await pending
print(first, await queue.get()) # first second
if __name__ == "__main__":
asyncio.run(main())
The first get frees a slot for the producer's second item. All we have done with the first item is save it in a variable; no separate business processing has started. This shows where waiting for a queue slot differs from waiting for the consumer to finish its work.