ProjectContextFactory: TakeSingleProjectContext
We replace ProjectContextFactory::NewSingleProjectContext() with
ProjectContextFactory::TakeSingleProjectContext(). With this
new method it is not necessary to keep the ProjectContextFactory
alive because the returned ProjectContext owns the underlying
data.
CB-220
This is part of a series of CLs whose goal is to clean up the client-side
infrastrcutrue around accessing the Cobalt Registry.
Change-Id: Icdc0f6dfe952ced40a51f7a72dee9eede1aefd48
diff --git a/logger/project_context_factory.cc b/logger/project_context_factory.cc
index f36d021..0e0d4cca 100644
--- a/logger/project_context_factory.cc
+++ b/logger/project_context_factory.cc
@@ -68,14 +68,17 @@
release_stage);
}
-std::unique_ptr<ProjectContext> ProjectContextFactory::NewSingleProjectContext(
+std::unique_ptr<ProjectContext> ProjectContextFactory::TakeSingleProjectContext(
ReleaseStage release_stage) {
if (!is_single_project()) {
return nullptr;
}
- return NewProjectContext(project_configs_->single_customer_name(),
- project_configs_->single_project_name(),
- release_stage);
+ auto project_context = std::make_unique<ProjectContext>(
+ project_configs_->single_customer_id(),
+ project_configs_->single_customer_name(),
+ project_configs_->TakeSingleProjectConfig(), release_stage);
+ project_configs_.reset();
+ return project_context;
}
std::unique_ptr<encoder::ProjectContext>
diff --git a/logger/project_context_factory.h b/logger/project_context_factory.h
index 2e93d7e..343aabe 100644
--- a/logger/project_context_factory.h
+++ b/logger/project_context_factory.h
@@ -41,12 +41,13 @@
// ProjectContext.
//
// Depending on which state the factory's CobaltRegistry is in, invoke one
-// of the New*() methods to create a new ProjectContext.
+// of the New*() or Take*() methods to retrieve a new ProjectContext().
//
-// Important: The ProjectContextFactory continues to own its CobaltRegistry.
-// The returned ProjectContext maintains a pointer to the CobaltRegistry
-// owned by the ProjectContextFactory. Thus the ProjectContextFactory must
-// not be destructed until after the ProjectContext is no longer being used.
+// Important: Pay attention to the notes on each method regarding the
+// requirement that this ProjectContextFactory remain alive. In some cases,
+// the returned ProjectContext contains a poiner into the CobaltRegistry
+// owned by this ProjectContextFactory and so the factory must not
+// be destructed until after the ProjectContext is no longer being used.
class ProjectContextFactory {
public:
// Constructs a ProjectContextFactory whose CobaltRegistry is obtained
@@ -80,20 +81,26 @@
// contains that project. The ProjectContext will be marked as being for a
// client at the given |release_stage|. Returns nullptr otherwise.
//
- // This ProjectContextFactory must remain alive as long as the returned
- // ProjectContext is being used.
+ // Important: The returned ProjectContext contains a pointer into this
+ // factory's CobaltRegistry. This ProjectContextFactory must remain alive as
+ // long as the returned ProjectContext is being used.
std::unique_ptr<ProjectContext> NewProjectContext(
std::string customer_name, std::string project_name,
ReleaseStage release_stage = GA);
- // If is_single_project() is true, returns a ProjectContext for the unique
- // Cobalt 1.0 project contained in the factory's CobaltRegistry. The
- // ProjectContext will be marked as being for a client at the given
- // |release_stage|. Returns nullptr otherwise.
+ // If is_single_project() is true, then this returns a
+ // ProjectContext for the unique Cobalt 1.0 project contained in the factory's
+ // CobaltRegistry and removes the corresponding data from the registry,
+ // leaving this ProjectContextFactory invalid. The returned ProjectContext
+ // will be marked as being for a client at the given |release_stage|.
+ // Returns nullptr otherwise.
//
- // This ProjectContextFactory must remain alive as long as the returned
- // ProjectContext is being used.
- std::unique_ptr<ProjectContext> NewSingleProjectContext(
+ // Note: The returned ProjectContext does *not* contain a pointer into
+ // this factory's CobaltRegistry because the appropriate data is removed
+ // from the CobaltRegistry and is now owned by the ProjectContext. If nullptr
+ // is not returned then this ProjectContextFactory becomes invalid and
+ // shoud be discarded.
+ std::unique_ptr<ProjectContext> TakeSingleProjectContext(
ReleaseStage release_stage = GA);
// Returns a ProjectContext for the Cobalt 0.1 project with the given
@@ -103,8 +110,9 @@
// CobaltRegistry for the specified project so the returned ProjectContext
// may be non-null but still empty.
//
- // This ProjectContextFactory must remain alive as long as the returned
- // ProjectContext is being used.
+ // Note: The returned ProjectContext contains a shared pointer into
+ // this factory's CobaltRegistry. It does not matter whether or not this
+ // ProjectContextFactory remains alive.
std::unique_ptr<encoder::ProjectContext> NewLegacyProjectContext(
uint32_t customer_id, uint32_t project_id);
@@ -112,8 +120,9 @@
// unique Cobalt 0.1 project contained in the factory's CobaltRegistry.
// Returns nullptr otherwise.
//
- // This ProjectContextFactory must remain alive as long as the returned
- // ProjectContext is being used.
+ // Note: The returned ProjectContext contains a shared pointer into
+ // this factory's CobaltRegistry. It does not matter whether or not this
+ // ProjectContextFactory remains alive.
std::unique_ptr<encoder::ProjectContext> NewSingleLegacyProjectContext();
private:
diff --git a/logger/project_context_factory_test.cc b/logger/project_context_factory_test.cc
index aecd141..b992d59 100644
--- a/logger/project_context_factory_test.cc
+++ b/logger/project_context_factory_test.cc
@@ -109,11 +109,9 @@
EXPECT_FALSE(factory.is_valid());
EXPECT_FALSE(factory.is_single_project());
EXPECT_FALSE(factory.is_single_legacy_project());
- EXPECT_EQ(nullptr,
- factory.NewProjectContext("Customer11", "Project11").get());
- EXPECT_EQ(nullptr,
- factory.NewProjectContext("Customer22", "Project22").get());
- EXPECT_EQ(nullptr, factory.NewSingleProjectContext().get());
+ EXPECT_EQ(nullptr, factory.NewProjectContext("Customer11", "Project11"));
+ EXPECT_EQ(nullptr, factory.NewProjectContext("Customer22", "Project22"));
+ EXPECT_EQ(nullptr, factory.TakeSingleProjectContext());
EXPECT_EQ(nullptr, factory.NewLegacyProjectContext(11, 11).get());
EXPECT_EQ(nullptr, factory.NewSingleLegacyProjectContext().get());
}
@@ -139,7 +137,7 @@
factory.NewProjectContext("Customer22", "Project22").get());
// Registry A does not contain a single Cobalt 1.0 project.
- EXPECT_EQ(nullptr, factory.NewSingleProjectContext().get());
+ EXPECT_EQ(nullptr, factory.TakeSingleProjectContext());
// Registry A does contain some Cobalt 0.1 project data.
EXPECT_NE(nullptr, factory.NewLegacyProjectContext(11, 11).get());
@@ -182,22 +180,21 @@
EXPECT_NE(nullptr,
factory.NewProjectContext("Customer22", "Project22").get());
- // Registry B does contain a single Cobalt 1.0 project.
- EXPECT_NE(nullptr, factory.NewSingleProjectContext().get());
-
// Registry B does not contain any Cobalt 0.1 project data.
EXPECT_EQ(nullptr, factory.NewLegacyProjectContext(11, 11).get());
EXPECT_EQ(nullptr, factory.NewSingleLegacyProjectContext().get());
+ // Registry B does contain a single Cobalt 1.0 project.
+ auto context = factory.TakeSingleProjectContext();
+ EXPECT_NE(nullptr, context);
+
// The single Cobalt 1.0 project contains metric 22 but not metric 11.
- auto context = factory.NewSingleProjectContext();
EXPECT_EQ(nullptr, context->GetMetric("Metric11"));
EXPECT_NE(nullptr, context->GetMetric("Metric22"));
- // Cobalt 1.0 project 22 contains metric 22 but not metric 11.
- context = factory.NewProjectContext("Customer22", "Project22");
- EXPECT_EQ(nullptr, context->GetMetric("Metric11"));
- EXPECT_NE(nullptr, context->GetMetric("Metric22"));
+ // The data has been removed from the factory.
+ EXPECT_EQ(nullptr, factory.NewProjectContext("Customer22", "Project22"));
+ EXPECT_FALSE(factory.is_valid());
}
TEST(ProjectContextFactoryTest, RegistryC) {
@@ -219,7 +216,7 @@
factory.NewProjectContext("Customer22", "Project22").get());
// Registry C does not contain only a single Cobalt 0.1 project.
- EXPECT_EQ(nullptr, factory.NewSingleProjectContext().get());
+ EXPECT_EQ(nullptr, factory.TakeSingleProjectContext());
// Registry C contains Cobalt 0.1 project 11 but not project 22.
EXPECT_NE(nullptr, factory.NewLegacyProjectContext(11, 11).get());