Closed elazarl closed 9 months ago
executor
is specified to be an object that just accepts a callable which itself is invokable such as cti::work
.
struct my_executor {
template<typename T>
void operator()(T&& callable) {
std::forward<T>(callable)(); // Can dispatach the callable from another thread.
}
};
The answer to your question is not directly related to continuable itself. You can always dispatch the start of your continuation chain from any thread e.g. by passing a lambda to the executor directly.
The only issue here is that for instance the cti::work object callable needs to be callable as r-value reference which usually is not the case for an ordinary lambda. A wrapper class can help out circumventing this, in case the executor accepts cti::work
directly:
template <typename Callable>
struct work_wrap_t {
template<typename... T>
auto operator()(T&&... args) &&
-> decltype(std::move(callable_)(std::forward<T>(args)...)) {
return std::move(callable_)(std::forward<T>(args)...);
}
Callable callable_;
};
executor(work_wrap_t([] {
this_thread.sleep_for(1s);
fmt::print("finished\n");
}));
Overall the answer to this question highly depends on the actual implementation of your executor and which parameters it accepts for initiating the dispatch.
I'm not entirely sure I understand.
How do I get a continuable from executor()
.
On the other hand, as you wrote, you can always use an executor directly in then expressions.
continuable<int> c;
c.then([](){foo();}, executor);
// equivalent to:
c.then([](){executor([](){foo();}});
So I'm still not sure, why is executor useful for then
, but not for make_continuable
?
I might be missing something fundamental here, so feel free to explain the very basics I got incorrectly.
Did you take a look into async_on
, maybe this is the solution to your question?
cti::continuable<> c1 = cti::async_on([] {
this_thread.sleep_for(1s);
fmt::print("finished\n");
}, executor)
Thanks. The problem I've had with that, is that the Callable
my executable accepts seems to be of the terse type
cti::detail::base::work_proxy<cti::detail::base::decoration::invoker<(lambda at /home/elazarl/.conan/data/continuable/4.2.1/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/continu
able/detail/core/base.hpp:339:7), cti::detail::identity<tl::expected<ns::elrond::mem_mgr::migration_result, std::error_condition>>>, (lambda at ../elrond/libs/mem_mgr/src
/mem_allocator.hpp:858:13), cti::detail::base::callbacks::final_callback<tl::expected<ns::elrond::mem_mgr::migration_result, std::error_condition>>>'
Which is not type-erasable to fu2::unique_function<void()>
. When I do that by hand, I'm passing a lambda there eventually, which is type erased.
It seems like this issue was resolved. If you have any further questions or issue reports open a new ticket please.
@Naios
continuable has a way to execute
then
on an executor.But Is it possible to create a new continuable over an executor?
Of course you can always do something like
But the documentation discourages you from making thy ready continuable in vain.