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