16 #include "tensorflow_serving/core/loader_harness.h"
22 #include "absl/log/log.h"
23 #include "absl/status/status.h"
24 #include "tensorflow/core/lib/core/errors.h"
25 #include "tensorflow/core/lib/strings/strcat.h"
26 #include "tensorflow/core/platform/env.h"
27 #include "tensorflow_serving/util/retrier.h"
29 namespace tensorflow {
32 LoaderHarness::LoaderHarness(
const ServableId&
id,
33 std::unique_ptr<Loader> loader,
34 const Options& options)
36 loader_(std::move(loader)),
37 additional_state_(nullptr),
39 should_retry_([&](absl::Status status) {
return true; }) {
40 VLOG(1) <<
"Starting to manage servable version " << id_;
43 LoaderHarness::~LoaderHarness() {
45 DCHECK(state_ == State::kNew || state_ == State::kDisabled ||
46 state_ == State::kError)
47 <<
"Servable: " << id_ <<
" state: " << state_;
55 Status LoaderHarness::LoadRequested() {
58 if (state_ != State::kNew) {
59 return errors::FailedPrecondition(
"Duplicate load request");
61 state_ = State::kLoadRequested;
62 VLOG(1) <<
"Load requested for servable version " << id_;
67 Status LoaderHarness::LoadApproved() {
70 TransitionState(State::kLoadRequested, State::kLoadApproved));
71 LOG(INFO) <<
"Approving load for servable version " << id_;
75 Status LoaderHarness::Load() {
78 TF_RETURN_IF_ERROR(TransitionState(State::kLoadApproved, State::kLoading));
79 LOG(INFO) <<
"Loading servable version " << id_;
82 const Status status = Retry(
83 strings::StrCat(
"Loading servable: ", id_.DebugString()),
84 options_.max_num_load_retries, options_.load_retry_interval_micros,
85 [&]() { return loader_->LoadWithMetadata({id_}); },
86 [&](absl::Status status) {
return should_retry(status); });
89 if (!should_retry(absl::UnknownError(
""))) {
93 TF_RETURN_IF_ERROR(UnloadDueToCancelledLoad());
94 return errors::Cancelled(
95 strings::StrCat(
"Loading of servable cancelled"));
99 TF_RETURN_IF_ERROR(TransitionState(State::kLoading, State::kReady));
100 LOG(INFO) <<
"Successfully loaded servable version " << id_;
104 ErrorInternal(status);
110 Status LoaderHarness::UnloadRequested() {
112 if (state_ != State::kReady) {
113 return errors::FailedPrecondition(
114 "Servable not loaded, or unload already requested/ongoing");
116 state_ = State::kUnloadRequested;
120 Status LoaderHarness::UnloadInternal(State from_state) {
123 TF_RETURN_IF_ERROR(TransitionState(from_state, State::kUnloading));
124 LOG(INFO) <<
"Unloading just-loaded servable version " << id_;
131 TF_RETURN_IF_ERROR(TransitionState(State::kUnloading, State::kDisabled));
132 LOG(INFO) <<
"Done unloading servable version " << id_;
137 Status LoaderHarness::UnloadDueToCancelledLoad() {
138 return UnloadInternal(State::kLoading);
141 void LoaderHarness::set_should_retry(
142 std::function<
bool(absl::Status)> should_retry) {
144 should_retry_ = std::move(should_retry);
147 bool LoaderHarness::should_retry(absl::Status status) {
149 return should_retry_(status);
152 Status LoaderHarness::Unload() {
return UnloadInternal(State::kQuiesced); }
154 Status LoaderHarness::StartQuiescing() {
157 TransitionState(State::kUnloadRequested, State::kQuiescing));
158 LOG(INFO) <<
"Quiescing servable version " << id_;
162 Status LoaderHarness::DoneQuiescing() {
164 TF_RETURN_IF_ERROR(TransitionState(State::kQuiescing, State::kQuiesced));
165 LOG(INFO) <<
"Done quiescing servable version " << id_;
169 void LoaderHarness::ErrorInternal(
const Status& status) {
170 state_ = State::kError;
172 if (options_.error_callback) {
173 options_.error_callback(
id(), status);
175 LOG(INFO) <<
"Encountered an error for servable version " << id_ <<
": "
179 void LoaderHarness::Error(
const Status& status) {
181 ErrorInternal(status);
184 Status LoaderHarness::TransitionState(
const State from,
const State to) {
185 if (state_ != from) {
186 const Status error = errors::Internal(
187 "Illegal request to transition from state ", StateDebugString(state_),
188 " to ", StateDebugString(to));
192 ErrorInternal(error);
200 Status LoaderHarness::status()
const {
205 string LoaderHarness::StateDebugString(
const State state) {
209 case State::kLoadRequested:
210 return "load-requested";
211 case State::kLoadApproved:
212 return "load-approved";
213 case State::kLoading:
217 case State::kUnloadRequested:
218 return "unload-requested";
219 case State::kQuiescing:
221 case State::kQuiesced:
223 case State::kUnloading:
225 case State::kDisabled: