westonpace commented on code in PR #14257:
URL: https://github.com/apache/arrow/pull/14257#discussion_r990346449
##########
cpp/src/arrow/util/async_util.cc:
##########
@@ -98,13 +98,54 @@ class FifoQueue : public AsyncTaskScheduler::Queue {
std::list<std::unique_ptr<Task>> tasks_;
};
+class AlreadyFailedScheduler : public AsyncTaskScheduler {
+ public:
+ explicit AlreadyFailedScheduler(Status failure_reason,
+ FnOnce<Status(Status)> finish_callback)
+ : failure_reason_(std::move(failure_reason)),
+ finish_callback_(std::move(finish_callback)) {}
+ bool AddTask(std::unique_ptr<Task> task) override { return false; }
+ void End() override {
+ std::ignore = std::move(finish_callback_)(failure_reason_);
+ self.reset();
+ }
+ Future<> OnFinished() const override {
+ Status::UnknownError(
+ "You should not rely on sub-scheduler's OnFinished. Use a "
+ "finished callback when creating the sub-scheduler instead")
+ .Abort();
+ }
+ AsyncTaskScheduler* MakeSubScheduler(FnOnce<Status(Status)> finish_callback,
+ Throttle* throttle,
+ std::unique_ptr<Queue> queue) override {
+ return AlreadyFailedScheduler::Make(failure_reason_,
std::move(finish_callback));
+ }
+ static AsyncTaskScheduler* Make(Status failure,
+ FnOnce<Status(Status)> finish_callback) {
+ DCHECK(!failure.ok());
+ std::unique_ptr<AlreadyFailedScheduler> instance =
+ std::make_unique<AlreadyFailedScheduler>(std::move(failure),
+ std::move(finish_callback));
+ AsyncTaskScheduler* view = instance.get();
+ instance->self = std::move(instance);
+ return view;
+ }
+ // This is deleted when ended so there is no possible way for this to return
true
+ bool IsEnded() override { return false; }
+
+ private:
+ Status failure_reason_;
+ FnOnce<Status(Status)> finish_callback_;
+ std::unique_ptr<AlreadyFailedScheduler> self;
Review Comment:
Agreed. One potentially bright side is that the leak will be the least of
the user's worries at that point because there will also be a deadlock (parent
scheduler cannot end if child scheduler doesn't end and so nothing will end).
I played around with it and created a solution with shared_ptr
(https://github.com/apache/arrow/commit/8652410772375cc4d7edfe071fd00e0204271a00)
but I don't know how much cleaner it really is. All of the real world calls
to `->End()` were simply replaced by `.reset()`.
I think the correct long-term solution for this is ARROW-17509 but I was
holding off on that so as not to introduce more change at this point. Let me
know which of the three you think would be best to proceed with:
* Keep as is
* Change to shared_ptr (more change but, IMHO, not clearly better)
* Remove calls to End entirely (larger change, best solution)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]