xref: /aosp_15_r20/external/federated-compute/fcp/client/interruptible_runner.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1*14675a02SAndroid Build Coastguard Worker /*
2*14675a02SAndroid Build Coastguard Worker  * Copyright 2020 Google LLC
3*14675a02SAndroid Build Coastguard Worker  *
4*14675a02SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*14675a02SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*14675a02SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*14675a02SAndroid Build Coastguard Worker  *
8*14675a02SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*14675a02SAndroid Build Coastguard Worker  *
10*14675a02SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*14675a02SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*14675a02SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*14675a02SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*14675a02SAndroid Build Coastguard Worker  * limitations under the License.
15*14675a02SAndroid Build Coastguard Worker  */
16*14675a02SAndroid Build Coastguard Worker #ifndef FCP_CLIENT_INTERRUPTIBLE_RUNNER_H_
17*14675a02SAndroid Build Coastguard Worker #define FCP_CLIENT_INTERRUPTIBLE_RUNNER_H_
18*14675a02SAndroid Build Coastguard Worker 
19*14675a02SAndroid Build Coastguard Worker #include <functional>
20*14675a02SAndroid Build Coastguard Worker #include <memory>
21*14675a02SAndroid Build Coastguard Worker 
22*14675a02SAndroid Build Coastguard Worker #include "absl/status/status.h"
23*14675a02SAndroid Build Coastguard Worker #include "absl/time/time.h"
24*14675a02SAndroid Build Coastguard Worker #include "fcp/base/future.h"
25*14675a02SAndroid Build Coastguard Worker #include "fcp/base/monitoring.h"
26*14675a02SAndroid Build Coastguard Worker #include "fcp/base/scheduler.h"
27*14675a02SAndroid Build Coastguard Worker #include "fcp/client/diag_codes.pb.h"
28*14675a02SAndroid Build Coastguard Worker #include "fcp/client/log_manager.h"
29*14675a02SAndroid Build Coastguard Worker 
30*14675a02SAndroid Build Coastguard Worker namespace fcp {
31*14675a02SAndroid Build Coastguard Worker namespace client {
32*14675a02SAndroid Build Coastguard Worker 
33*14675a02SAndroid Build Coastguard Worker // An executor that runs operations in a background thread, polling a callback
34*14675a02SAndroid Build Coastguard Worker // periodically whether to abort, and aborting the operation if necessary.
35*14675a02SAndroid Build Coastguard Worker // This uses a single-threaded thread pool. During execution of an operation,
36*14675a02SAndroid Build Coastguard Worker // should_abort is polled periodically (polling_period), and if it returns true,
37*14675a02SAndroid Build Coastguard Worker // the abort_function supplied along with the operation is called. The operation
38*14675a02SAndroid Build Coastguard Worker // is then expected to abort within graceful_shutdown_period. If not, a diag
39*14675a02SAndroid Build Coastguard Worker // code is logged and we wait for some time longer (extended_shutdown_period),
40*14675a02SAndroid Build Coastguard Worker // and if the operation still does not finish, the program exits.
41*14675a02SAndroid Build Coastguard Worker // The destructor blocks until the background thread has become idle.
42*14675a02SAndroid Build Coastguard Worker class InterruptibleRunner {
43*14675a02SAndroid Build Coastguard Worker  public:
44*14675a02SAndroid Build Coastguard Worker   // A struct used to group polling & timeout related parameters.
45*14675a02SAndroid Build Coastguard Worker   struct TimingConfig {
46*14675a02SAndroid Build Coastguard Worker     absl::Duration polling_period;
47*14675a02SAndroid Build Coastguard Worker     absl::Duration graceful_shutdown_period;
48*14675a02SAndroid Build Coastguard Worker     absl::Duration extended_shutdown_period;
49*14675a02SAndroid Build Coastguard Worker   };
50*14675a02SAndroid Build Coastguard Worker 
51*14675a02SAndroid Build Coastguard Worker   // A struct used to group diagnostics related parameters.
52*14675a02SAndroid Build Coastguard Worker   struct DiagnosticsConfig {
53*14675a02SAndroid Build Coastguard Worker     ProdDiagCode interrupted;
54*14675a02SAndroid Build Coastguard Worker     ProdDiagCode interrupt_timeout;
55*14675a02SAndroid Build Coastguard Worker     ProdDiagCode interrupted_extended;
56*14675a02SAndroid Build Coastguard Worker     ProdDiagCode interrupt_timeout_extended;
57*14675a02SAndroid Build Coastguard Worker   };
58*14675a02SAndroid Build Coastguard Worker 
InterruptibleRunner(LogManager * log_manager,std::function<bool ()> should_abort,const TimingConfig & timing_config,const DiagnosticsConfig & diagnostics_config)59*14675a02SAndroid Build Coastguard Worker   InterruptibleRunner(LogManager* log_manager,
60*14675a02SAndroid Build Coastguard Worker                       std::function<bool()> should_abort,
61*14675a02SAndroid Build Coastguard Worker                       const TimingConfig& timing_config,
62*14675a02SAndroid Build Coastguard Worker                       const DiagnosticsConfig& diagnostics_config)
63*14675a02SAndroid Build Coastguard Worker       : log_manager_(log_manager),
64*14675a02SAndroid Build Coastguard Worker         should_abort_(should_abort),
65*14675a02SAndroid Build Coastguard Worker         timing_config_(timing_config),
66*14675a02SAndroid Build Coastguard Worker         diagnostics_config_(diagnostics_config) {
67*14675a02SAndroid Build Coastguard Worker     thread_pool_ = fcp::CreateThreadPoolScheduler(1);
68*14675a02SAndroid Build Coastguard Worker   }
69*14675a02SAndroid Build Coastguard Worker 
~InterruptibleRunner()70*14675a02SAndroid Build Coastguard Worker   ~InterruptibleRunner() { thread_pool_->WaitUntilIdle(); }
71*14675a02SAndroid Build Coastguard Worker 
72*14675a02SAndroid Build Coastguard Worker   // Executes f() on a background. Returns CANCELLED if the background thread
73*14675a02SAndroid Build Coastguard Worker   // was aborted, or a Status object from the background thread on successful
74*14675a02SAndroid Build Coastguard Worker   // completion.
75*14675a02SAndroid Build Coastguard Worker   absl::Status Run(std::function<absl::Status()> f,
76*14675a02SAndroid Build Coastguard Worker                    std::function<void()> abort_function);
77*14675a02SAndroid Build Coastguard Worker 
78*14675a02SAndroid Build Coastguard Worker  private:
79*14675a02SAndroid Build Coastguard Worker   absl::Status WaitUntilDone(fcp::thread::Future<absl::Status>&& run_future,
80*14675a02SAndroid Build Coastguard Worker                              std::function<void()> abort_function);
81*14675a02SAndroid Build Coastguard Worker   absl::Status Abort(fcp::thread::Future<absl::Status> run_future,
82*14675a02SAndroid Build Coastguard Worker                      std::function<void()> abort_function);
83*14675a02SAndroid Build Coastguard Worker 
84*14675a02SAndroid Build Coastguard Worker   std::unique_ptr<Scheduler> thread_pool_;
85*14675a02SAndroid Build Coastguard Worker   LogManager* const log_manager_;
86*14675a02SAndroid Build Coastguard Worker   std::function<bool()> should_abort_;
87*14675a02SAndroid Build Coastguard Worker   TimingConfig timing_config_;
88*14675a02SAndroid Build Coastguard Worker   DiagnosticsConfig diagnostics_config_;
89*14675a02SAndroid Build Coastguard Worker };
90*14675a02SAndroid Build Coastguard Worker 
91*14675a02SAndroid Build Coastguard Worker }  // namespace client
92*14675a02SAndroid Build Coastguard Worker }  // namespace fcp
93*14675a02SAndroid Build Coastguard Worker 
94*14675a02SAndroid Build Coastguard Worker #endif  // FCP_CLIENT_INTERRUPTIBLE_RUNNER_H_
95