with send_channel, receive_channel:
async with anyio.create_task_group() as task_group:
might be better as
async with anyio.create_task_group() as task_group:
with send_channel, receive_channel:
this way closing the amap context manager (None, None, None)ly would allow currently running tasks to finish, and prevent new tasks being added. Closing the amap context manager (type[T], T, tb)ly would still cancel all tasks