-
Type: Improvement
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
Fully Compatible
-
Service Arch 2021-11-15, Service Arch 2021-11-22, Service Arch 2021-12-13, Service Arch 2022-1-10, Service Arch 2022-1-24
-
4
Sometimes, you have some code that will be run asynchronously at some point in the future. You want to know when that code is done running. Here's what you can do now:
auto task = makeMyTask(); // task is some Callable auto fut = ExecutorFuture(_exec).then(task()); // fut will resolve once task is done running
But what if you want to have access to `fut` before you actually schedule task? For example:
class MyLittleService { public: SharedSemiFuture<void> isTaskDoneFuture( return _isDoneFuture) void start() { _isDoneFuture = ExecutorFuture(_exec).then(_task().share()); } private: TaskType _task = makeMyTask(); SharedSemiFuture<void> _isDoneFuture }
But this code won't compile, because SharedSemiFuture has no default constructor. Instead, we would need to make _isDoneFuture an optional, and only give it a value when the task is actually scheduled. (Yuck!) What we want is a future that is readied when task is run, that can safely be created and used even before task is scheduled.
This is what packaged_task does :https://en.cppreference.com/w/cpp/thread/packaged_task
We could rewrite our above example as follows:
class MyLittleService { public: SharedSemiFuture<void> isTaskDoneFuture( return _task.getFuture()) void start() { ExecutorFuture(_exec).then(_task().share()); } private: PackegedTask _task = makePackagedTask(makeMyTask()); }
Futures extracted via _task.getFuture() will be readied when task has executed and contain the value returned by task (or exceptions it threw).