continuable
continuable copied to clipboard
Reusable continuation chains
Thanks for this fantastic library @Naios. The amount of work you must have put into the documentation is really appreciated.
I'm wondering whether reusable continuation chains are a planned feature, or indeed whether your implementation even permits such a thing? If it is possible, could you please give a brief summary of what would need to be done/how it should be approached? I'd be interested in implementing such a thing and would appreciate your thoughts.
I'm glad that you like the library and especially the documentation which took a lot of effort indeed.
I thought about reusable continuation chains before and the core library is well suited for such an implementation, when putting connections aside.
Currently the plain callback interface looks like this:
template<typename... Args>
struct callback {
void operator() (Args...) &&;
void operator() (cti::exception_arg_t, cti::exception_t) &&;
};
Because the library treats continuiables as a use once object the continuation chain which was already invoked is left behind while the chain to come is moved into the next continuation. This is also reflected by the continuation interface which acceps the next callback as a whole:
template<typename... Args>
struct continuation {
void operator() (callback<Args...>);
bool operator() (cti::is_ready_arg_t) const;
std::tuple<Args...> operator() (cti::query_arg_t);
};
Further we call a reusable continuation channel
and its reusable promise type sink
.
In order to make such a feature to work one must change the behaviour of callback propagation such that the callbacks are not moved but kept through the continuation chain.
template<typename... Args>
struct callback {
void operator() (Args...);
void operator() (cti::exception_arg_t, cti::exception_t);
};
The main file which must be changed for this is include/continuable/detail/core/base.hpp through changing the moves to pass by l-value reference.
https://github.com/Naios/continuable/blob/fdd9a061c4d1b808e550f519bba400b2cfa2eea6/include/continuable/detail/core/base.hpp#L548
Further a new wrapper class for continuable
-> channel
and promise
-> sink
needs to be introduced and make continuable
and channel
interoperable where applyable.
Probably it won't be that simple as described above but this is the basic idea I think. Let me know if you need further help on this.
Thanks for your detailed reply; it will be very useful. I'll report back here with my progress (though it likely won't be for a couple of months).
I was hoping to implement connections for channel
s too, but you hinted above that it's not possible. What is currently blocking the implementation of connections between channel
s?
Basically the when_seq
and when_all
connection are the difficult ones. when_any
is probably tirivial to implement.
The issue will be to cache multiple results of many channels and then dispatch them to the waiting channels in order. The difference to the use once chain is that many connection frames with different progresses can wait on the next result of one channel.
(async_generate_some_int() && async_generate_some_chars()).then([] (int a, char b) {
// will wait on pairs such that a and b is available
})