Skip to content

Commit 2608f8d

Browse files
author
Christopher Olston
committed
Merge pull request #28 from kirilg/branch_118386107
Upstream changes from internal
2 parents 6eba8a3 + 8163c89 commit 2608f8d

27 files changed

+870
-113
lines changed

tensorflow_serving/core/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ cc_test(
310310
":eager_load_policy",
311311
":servable_state",
312312
"//tensorflow_serving/core/test_util:dynamic_manager_test_util",
313+
"//tensorflow_serving/core/test_util:fake_loader",
313314
"//tensorflow_serving/core/test_util:mock_loader",
314315
"//tensorflow_serving/core/test_util:test_main",
315316
"//tensorflow_serving/util:any_ptr",

tensorflow_serving/core/availability_helpers.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ namespace tensorflow {
2626
namespace serving {
2727
namespace {
2828

29-
bool ServablesAvailable(Manager* const manager,
30-
const std::vector<ServableRequest>& servables) {
29+
// Implements the test logic of WaitUntilServablesAvailableForRequests().
30+
bool ServablesAvailableForRequests(
31+
const std::vector<ServableRequest>& servables, Manager* const manager) {
3132
// The subset of 'servables' that require a specific version
3233
std::set<ServableId> query_specific_servables;
3334
// The subset of 'servables' that do not require a specific version
@@ -69,12 +70,21 @@ bool ServablesAvailable(Manager* const manager,
6970

7071
} // namespace
7172

72-
void WaitUntilServablesAvailable(
73-
Manager* const manager, const std::vector<ServableRequest>& servables) {
74-
while (!ServablesAvailable(manager, servables)) {
73+
void WaitUntilServablesAvailableForRequests(
74+
const std::vector<ServableRequest>& servables, Manager* const manager) {
75+
while (!ServablesAvailableForRequests(servables, manager)) {
7576
Env::Default()->SleepForMicroseconds(50 * 1000 /* 50 ms */);
7677
}
7778
}
7879

80+
void WaitUntilServablesAvailable(const std::set<ServableId>& servables,
81+
Manager* const manager) {
82+
std::vector<ServableRequest> requests;
83+
for (const ServableId& id : servables) {
84+
requests.push_back(ServableRequest::FromId(id));
85+
}
86+
return WaitUntilServablesAvailableForRequests(requests, manager);
87+
}
88+
7989
} // namespace serving
8090
} // namespace tensorflow

tensorflow_serving/core/availability_helpers.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ namespace serving {
4141
// polling is 50ms. We call ListAvailableServableIds on the manager, which may
4242
// have side-effects for certain manager implementations, e.g. causing servables
4343
// to be loaded.
44-
void WaitUntilServablesAvailable(Manager* manager,
45-
const std::vector<ServableRequest>& servables);
44+
void WaitUntilServablesAvailableForRequests(
45+
const std::vector<ServableRequest>& servables, Manager* manager);
46+
47+
// Like WaitUntilServablesAvailableForRequests(), but taking a set of servable
48+
// ids (and hence waits for the specific versions specified in the ids).
49+
void WaitUntilServablesAvailable(const std::set<ServableId>& servables,
50+
Manager* manager);
4651

4752
} // namespace serving
4853
} // namespace tensorflow

tensorflow_serving/core/availability_helpers_test.cc

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,20 @@ class FakeManager : public Manager {
6666
condition_variable list_available_servable_ids_condition_;
6767
};
6868

69-
TEST(AvailabilityHelpersTest, Available) {
70-
std::vector<ServableRequest> available_servables_query;
71-
available_servables_query.emplace_back(
72-
ServableRequest::Specific("servable0", 0));
69+
TEST(AvailabilityHelpersTest, SpecificAvailable) {
7370
FakeManager fake_manager;
7471
fake_manager.set_available_servable_ids({{"servable0", 0}});
75-
WaitUntilServablesAvailable(&fake_manager, available_servables_query);
72+
WaitUntilServablesAvailable({{"servable0", 0}}, &fake_manager);
7673
}
7774

7875
TEST(AvailabilityHelpersTest, SpecificNotAvailable) {
7976
FakeManager fake_manager;
8077
fake_manager.set_available_servable_ids({{"servable0", 0}});
81-
const std::vector<ServableRequest> available_servables_query = {
82-
ServableRequest::Specific("servable0", 0),
83-
ServableRequest::Specific("servable1", 0)};
8478
Notification finished;
8579
std::unique_ptr<Thread> wait(
8680
Env::Default()->StartThread({}, "WaitUntilServablesAvailable", [&]() {
87-
WaitUntilServablesAvailable(&fake_manager, available_servables_query);
81+
WaitUntilServablesAvailable({{"servable0", 0}, {"servable1", 0}},
82+
&fake_manager);
8883
finished.Notify();
8984
}));
9085
// Waiting for 2 calls ensures that we waited at least once for the servables
@@ -98,13 +93,13 @@ TEST(AvailabilityHelpersTest, SpecificNotAvailable) {
9893
TEST(AvailabilityHelpersTest, LatestNotAvailable) {
9994
FakeManager fake_manager;
10095
fake_manager.set_available_servable_ids({{"servable0", 0}});
101-
const std::vector<ServableRequest> available_servables_query = {
102-
ServableRequest::Specific("servable0", 0),
103-
ServableRequest::Latest("servable1")};
10496
Notification finished;
10597
std::unique_ptr<Thread> wait(
10698
Env::Default()->StartThread({}, "WaitUntilServablesAvailable", [&]() {
107-
WaitUntilServablesAvailable(&fake_manager, available_servables_query);
99+
WaitUntilServablesAvailableForRequests(
100+
{ServableRequest::Specific("servable0", 0),
101+
ServableRequest::Latest("servable1")},
102+
&fake_manager);
108103
finished.Notify();
109104
}));
110105
// Waiting for 2 calls ensures that we waited at least once for the servables
@@ -116,21 +111,19 @@ TEST(AvailabilityHelpersTest, LatestNotAvailable) {
116111
}
117112

118113
TEST(AvailabilityHelpersTest, LatestVersion) {
119-
std::vector<ServableRequest> available_servables_query;
120-
available_servables_query.emplace_back(ServableRequest::Latest("servable0"));
121114
FakeManager fake_manager;
122115
fake_manager.set_available_servable_ids({{"servable0", 123}});
123-
WaitUntilServablesAvailable(&fake_manager, available_servables_query);
116+
WaitUntilServablesAvailableForRequests({ServableRequest::Latest("servable0")},
117+
&fake_manager);
124118
}
125119

126120
TEST(AvailabilityHelpersTest, LatestAndExactVersion) {
127-
std::vector<ServableRequest> available_servables_query;
128-
available_servables_query.emplace_back(ServableRequest::Latest("servable0"));
129-
available_servables_query.emplace_back(
130-
ServableRequest::Specific("servable1", 1));
131121
FakeManager fake_manager;
132122
fake_manager.set_available_servable_ids({{"servable0", 0}, {"servable1", 1}});
133-
WaitUntilServablesAvailable(&fake_manager, available_servables_query);
123+
WaitUntilServablesAvailableForRequests(
124+
{ServableRequest::Latest("servable0"),
125+
ServableRequest::Specific("servable1", 1)},
126+
&fake_manager);
134127
}
135128

136129
} // namespace

tensorflow_serving/core/dynamic_manager_test.cc

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ limitations under the License.
2828
#include "tensorflow_serving/core/eager_load_policy.h"
2929
#include "tensorflow_serving/core/servable_state.h"
3030
#include "tensorflow_serving/core/test_util/dynamic_manager_test_util.h"
31+
#include "tensorflow_serving/core/test_util/fake_loader.h"
3132
#include "tensorflow_serving/core/test_util/mock_loader.h"
3233
#include "tensorflow_serving/util/any_ptr.h"
3334
#include "tensorflow_serving/util/event_bus.h"
@@ -36,40 +37,14 @@ namespace tensorflow {
3637
namespace serving {
3738

3839
using ::testing::_;
39-
using ::testing::Eq;
4040
using ::testing::Invoke;
4141
using ::testing::NiceMock;
4242
using ::testing::Return;
4343
using ::testing::UnorderedElementsAreArray;
44+
using test_util::FakeLoader;
4445

4546
namespace {
4647

47-
class FakeLoader : public ResourceUnsafeLoader {
48-
public:
49-
explicit FakeLoader(int64 servable, const bool errors_on_load = false)
50-
: servable_(servable), errors_on_load_(errors_on_load) {}
51-
~FakeLoader() override { --num_fake_loaders_; }
52-
53-
Status Load() override {
54-
if (errors_on_load_) {
55-
return errors::Internal("Error on load.");
56-
} else {
57-
return Status::OK();
58-
}
59-
}
60-
void Unload() override {}
61-
AnyPtr servable() override { return AnyPtr(&servable_); }
62-
static int num_fake_loaders() { return num_fake_loaders_; }
63-
64-
private:
65-
// Counts the number of Fakeloader objects alive.
66-
static int num_fake_loaders_;
67-
int64 servable_;
68-
// Whether to return an error when Load is called.
69-
const bool errors_on_load_;
70-
};
71-
int FakeLoader::num_fake_loaders_ = 0;
72-
7348
constexpr char kServableName[] = "kServableName";
7449
constexpr char kServableName2[] = "kServableName2";
7550
constexpr int kNumVersionsPerServable = 2;
@@ -227,7 +202,8 @@ TEST_F(DynamicManagerTest, ListAvailableServableIds) {
227202
// so never moves to a loaded state.
228203
std::vector<ServableData<std::unique_ptr<Loader>>> aspired_versions;
229204
const ServableId id = {kServableName, 7};
230-
std::unique_ptr<Loader> loader(new FakeLoader(7, true /* errors_on_load */));
205+
std::unique_ptr<Loader> loader(
206+
new FakeLoader(7, errors::Internal("Error on load.")));
231207
aspired_versions.push_back({id, std::move(loader)});
232208
manager_->GetAspiredVersionsCallback()(kServableName,
233209
std::move(aspired_versions));
@@ -496,7 +472,8 @@ TEST_F(DynamicManagerTest, EventBusErroneousVersion) {
496472
TEST_F(DynamicManagerTest, EventBusErrorOnLoad) {
497473
std::vector<ServableData<std::unique_ptr<Loader>>> aspired_versions;
498474
const ServableId id = {kServableName, 7};
499-
std::unique_ptr<Loader> loader(new FakeLoader(7, true /* errors_on_load */));
475+
std::unique_ptr<Loader> loader(
476+
new FakeLoader(7, errors::Internal("Error on load.")));
500477
aspired_versions.push_back({id, std::move(loader)});
501478
manager_->GetAspiredVersionsCallback()(kServableName,
502479
std::move(aspired_versions));
@@ -613,7 +590,8 @@ TEST_F(DynamicManagerTest, RetryOnLoadErrorFinallyFails) {
613590
std::vector<ServableData<std::unique_ptr<Loader>>> aspired_versions;
614591
const ServableId id = {kServableName, 7};
615592
// We always fail.
616-
std::unique_ptr<Loader> loader(new FakeLoader(7, true /* errors_on_load */));
593+
std::unique_ptr<Loader> loader(
594+
new FakeLoader(7, errors::Internal("Error on load.")));
617595
aspired_versions.push_back({id, std::move(loader)});
618596
manager_->GetAspiredVersionsCallback()(kServableName,
619597
std::move(aspired_versions));

tensorflow_serving/core/manager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct ServableRequest {
3838
// Initialization factories, for convenience and readability.
3939
static ServableRequest Specific(const string& name, const int64 version);
4040
static ServableRequest Latest(const string& name);
41+
static ServableRequest FromId(const ServableId& id);
4142

4243
// The name of a servable stream.
4344
string name;
@@ -89,6 +90,11 @@ inline ServableRequest ServableRequest::Latest(const string& name) {
8990
return ServableRequest{name, nullopt};
9091
}
9192

93+
inline ServableRequest ServableRequest::FromId(const ServableId& id) {
94+
DCHECK_GE(id.version, 0);
95+
return Specific(id.name, id.version);
96+
}
97+
9298
inline string ServableRequest::DebugString() const {
9399
if (version) {
94100
return strings::StrCat("Specific(", name, ", ", version.value(), ")");

tensorflow_serving/core/manager_test.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,24 @@ TEST(ServableHandleTest, PointerOps) {
169169
EXPECT_EQ(&servables[0].member, &handles[0]->member);
170170
}
171171

172+
TEST(ServableRequestTest, Specific) {
173+
const auto request = ServableRequest::Specific("servable", 7);
174+
EXPECT_EQ("servable", request.name);
175+
EXPECT_EQ(7, *request.version);
176+
}
177+
178+
TEST(ServableRequestTest, Latest) {
179+
const auto request = ServableRequest::Latest("servable");
180+
EXPECT_EQ("servable", request.name);
181+
EXPECT_FALSE(request.version);
182+
}
183+
184+
TEST(ServableRequestTest, FromId) {
185+
const auto request = ServableRequest::FromId({"servable", 7});
186+
EXPECT_EQ("servable", request.name);
187+
EXPECT_EQ(7, *request.version);
188+
}
189+
172190
} // namespace
173191

174192
} // namespace serving

tensorflow_serving/core/test_util/BUILD

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ cc_library(
4949
],
5050
)
5151

52+
cc_library(
53+
name = "fake_loader",
54+
testonly = 1,
55+
srcs = ["fake_loader.cc"],
56+
hdrs = ["fake_loader.h"],
57+
deps = [
58+
"@tf//tensorflow/core:lib",
59+
"//tensorflow_serving/core:loader",
60+
"//tensorflow_serving/util:any_ptr",
61+
],
62+
)
63+
5264
cc_library(
5365
name = "mock_storage_path_target",
5466
testonly = 1,
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* Copyright 2016 Google Inc. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
==============================================================================*/
15+
16+
#include "tensorflow_serving/core/test_util/fake_loader.h"
17+
18+
#include "tensorflow/core/lib/core/errors.h"
19+
20+
namespace tensorflow {
21+
namespace serving {
22+
namespace test_util {
23+
24+
thread_local bool FakeLoader::was_deleted_in_this_thread_;
25+
int FakeLoader::num_fake_loaders_ = 0;
26+
mutex FakeLoader::num_fake_loaders_mu_(LINKER_INITIALIZED);
27+
28+
FakeLoader::FakeLoader(int64 servable, const Status load_status)
29+
: servable_(servable), load_status_(load_status) {
30+
was_deleted_in_this_thread_ = false;
31+
{
32+
mutex_lock l(num_fake_loaders_mu_);
33+
++num_fake_loaders_;
34+
}
35+
}
36+
37+
FakeLoader::~FakeLoader() {
38+
{
39+
mutex_lock l(num_fake_loaders_mu_);
40+
--num_fake_loaders_;
41+
}
42+
was_deleted_in_this_thread_ = true;
43+
}
44+
45+
Status FakeLoader::load_status() { return load_status_; }
46+
47+
Status FakeLoader::Load() { return load_status_; }
48+
49+
void FakeLoader::Unload() {}
50+
51+
AnyPtr FakeLoader::servable() { return AnyPtr(&servable_); }
52+
53+
bool FakeLoader::was_deleted_in_this_thread() {
54+
return was_deleted_in_this_thread_;
55+
}
56+
57+
int FakeLoader::num_fake_loaders() {
58+
mutex_lock l(num_fake_loaders_mu_);
59+
return num_fake_loaders_;
60+
}
61+
62+
} // namespace test_util
63+
} // namespace serving
64+
} // namespace tensorflow

0 commit comments

Comments
 (0)