New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
in py3.8+ the first asyncio.Task object is allocated with the same ID every time #324
Comments
…anyio.abc.TaskInfo equality agronholm/anyio#324
@agronholm I think this is a bug in Trio too - it's just convenient that trio tasks happen not to be allocated in the same location |
…anyio.abc.TaskInfo equality agronholm/anyio#324
) * ensure TestClient requests run in the same EventLoop as lifespan * for lifespan task verification, use native task identity rather than anyio.abc.TaskInfo equality agronholm/anyio#324 * remove redundant pragma: no cover * it's now a loop_id not a threading.ident * replace Protocol with plain Callable TypeAlias * use lifespan_context to actually open a task group trio should complain if used incorrectly here. * assign self.portal once, schedule reset immediately after assignment * inline apps into their tests * make task/loop trackers nonlocals
I think anyio should maintain its own counter of tasks and use a WeakKeyDictionary to lookup tasks in and return that count |
But since AnyIO is not responsible for creating all tasks, how would that counter work? |
Anyio would need to maintain a WeakKeyDictionary from the concrete task object to a TaskInfo |
I don't understand how that relates to counters. What are we counting then? |
number of TaskInfo objects created, eg: @dataclass
class TaskInfo:
...
id = field(default_factory=itertools.count().__next__, init=False) |
Ok, but that means that IDs would not necessarily be in the same sequence that the underlying Tasks are created. Are we okay with that? |
well they're not currently in sequence, they're just the whim of the allocator |
Alright. Then, finally, could there be a situation where an underlying Task could be assigned two artificial IDs through two TaskInfo objects, perhaps when the first TaskInfo has been destroyed? Would that even be a problem? |
anyio task ids would be in sequence if TaskInfo objects are created eagerly when the _task_state entry is created. |
Wouldn't the TaskInfo live as long as the Task? |
They currently don't – they are throwaway objects which only live as long the recipient carries them in scope. |
|
By task do you mean |
something like this? _task_infos = WeakKeyDictionary[object, TaskInfo]
_counter = itertools.count()
class TaskInfo:
def __init__(self, task):
self.id = next(_counter)
ti = get_async_lib().extract_task_info(task)
self.parent_id = ti.parent_id
self.coro = ti.coro
def get_current_task_token():
library = sniffio.current_async_library()
if library == "trio":
return trio.lowlevel.current_task()
elif library == "asyncio":
return asyncio.current_task()
else:
raise RuntimeError("unsupported")
def get_current_task():
task = get_current_task_token()
try:
return _task_infos[task]
except KeyError:
_task_infos[task] = task_info = TaskInfo(task)
return task_info |
Right, if we keep the |
…213) * ensure TestClient requests run in the same EventLoop as lifespan * for lifespan task verification, use native task identity rather than anyio.abc.TaskInfo equality agronholm/anyio#324 * remove redundant pragma: no cover * it's now a loop_id not a threading.ident * replace Protocol with plain Callable TypeAlias * use lifespan_context to actually open a task group trio should complain if used incorrectly here. * assign self.portal once, schedule reset immediately after assignment * inline apps into their tests * make task/loop trackers nonlocals
…213) * ensure TestClient requests run in the same EventLoop as lifespan * for lifespan task verification, use native task identity rather than anyio.abc.TaskInfo equality agronholm/anyio#324 * remove redundant pragma: no cover * it's now a loop_id not a threading.ident * replace Protocol with plain Callable TypeAlias * use lifespan_context to actually open a task group trio should complain if used incorrectly here. * assign self.portal once, schedule reset immediately after assignment * inline apps into their tests * make task/loop trackers nonlocals
This is a problem in anyio because TaskInfo's
__eq__
goes on to compare dead object IDsThe text was updated successfully, but these errors were encountered: