Coroutines and any_sender
Closed this issue · 0 comments
Issue
I would like to use any_sender
with coroutines via let_value
.
any_sender concat(any_sender&& a, auto&& coroutine)
{
return stdexec::let_value(std::move(a), std::move(coroutine));
}
An error occurs during connect, because the connect function can't be called.
My investigation result
The chain looks something like:
- Error occurs when the any_sender is constructed and the vtable is built up
- It tries to make the connect call
- It goes to the set_value tag invoke
- It ends up in the let_value. Here the
sender
is atask
and the receiver isany_rec_ref
Here the connect can't be called due to the environment.
Actually the problem that the task
is not awaitable
with the context (environment) of the any_rec_ref
.
the task
is awaitable
only if it is an indirect_scheduler_provider.
Here the promise is the connec_t promise which forwards the receiver environment which ends up at any_rec_ref
.
So the environment of the any_rec_ref
is
- not a scheduler provider (its query is not forwarded)
- and the
task
has thedefault_task_context
which has a scheduler.
It makes the concept not fulfilled and causing that task
is not awaitable
with any_rec_ref
My two attempt to solve the issue:
With raw sender
I thought I can try to eliminate the issue with making the task to not have a scheduler. Actually it works but this type is 'private' and also feel a bit hacky solution. exec::basic_task<T, exec::__task::__raw_task_context<T>>;
Making the scheduler queriable in any_rec_ref
I thought using the ReceiversQuery template arguments of any_rec will solve the issue. But it failed with compile error. Looking around in the code it looks like never used and also stop_token is not provided via __query_vfun
. The basic error that __query_vfun
expects a signature and it receives a Tag. And for this the operator
is not implemented.
Summary
I think the ideal solution would be to make the any_rec_ref
be able to forward queries. (I'm also opened to create the PR but need some help to see how should the current __query_vfun work. I felt trying to modify it might break other - currently working - functionalities)
Test Code
https://godbolt.org/z/rjW3vWojW
Here there are 3 macros to control the scenarios:
- USE_RAW_TASK: When true raw task type is used and it compiles
- USE_TYPE_ERASE: When it is true it uses any_sender. When it is false it uses the sexpr and all works (like a sanity check)
- USE_QUERIES: Try to use the receiver queries with
get_scheduler