Skip to content

Tasks are not handling and propagating cancellations via keyboard interrupt #8

Description

@kchantrell-codan

Action: Run a taskpool and hit ctrl-C.

Actual behaviour: New tasks are not created and running tasks run to completion. The cancel callback is not triggered and CancelledError is not ever raised.

Expected behaviour: The cancel_callback is triggered and (maybe) CancelledError is raised by the caller and/or the running the tasks.

Example using asyncio-taskpool TaskPool.map():

import asyncio
import sys
import time
from asyncio import CancelledError

import asyncio_taskpool
from asyncio_taskpool import TaskPool


async def long_process(value: int) -> None:
    try:
        time.sleep(3.0)
        print(f"Processed: {value}")
    except CancelledError as e:
        print(f"Cancelled in process: {e}")
        raise


async def handle_cancel(task_id: int) -> None:
    print(f"Cancelled: {task_id}")


async def handle_end(task_id: int) -> None:
    print(f"Ended: {task_id}")


async def run() -> None:
    pool = TaskPool(1, "my_pool")
    pool.map(long_process, range(100), 1, end_callback=handle_end, cancel_callback=handle_cancel)
    await pool.gather_and_close()
    print("Clean exit.")


print(f"Python version: {sys.version}")
print(f"asyncio_taskpool version: {asyncio_taskpool.__version__}")

asyncio.run(run())

Result (note, no indication of the cancellation or keyboard interrupt):

> python test_asyncio_taskpool.py 
Python version: 3.13.1 (main, Dec  4 2024, 08:54:14) [GCC 9.4.0]
asyncio_taskpool version: 1.2.0
Processed: 0
Ended: 0
Processed: 1
Ended: 1
^CProcessed: 2
Ended: 2
Clean exit.

Successful example using standard asyncio tasks:

import asyncio
import sys
import time
from asyncio import CancelledError


async def long_process(value: int) -> None:
    try:
        time.sleep(3.0)
        print(f"Processed: {value}")
    except CancelledError as e:
        print(f"Cancelled in process: {e}")
        raise


async def run() -> None:
    try:
        await asyncio.gather(
            long_process(1),
            long_process(2),
            long_process(3),
            long_process(4),
            long_process(5),
        )
        print("Clean exit.")
    except CancelledError:
        print("Cancelled.")


print(f"Python version: {sys.version}")

asyncio.run(run())

Result:

> python test_asyncio.py
Python version: 3.13.1 (main, Dec  4 2024, 08:54:14) [GCC 9.4.0]
Processed: 1
^CProcessed: 2
Cancelled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions