Introduce api to disable service default initialization.

PiperOrigin-RevId: 515501608
This commit is contained in:
MediaPipe Team 2023-03-09 18:55:28 -08:00 committed by Copybara-Service
parent ef4a8cde42
commit 05b505c8e2
2 changed files with 38 additions and 1 deletions

View File

@ -631,7 +631,13 @@ absl::Status CalculatorGraph::PrepareServices() {
for (const auto& [key, request] : node->Contract().ServiceRequests()) { for (const auto& [key, request] : node->Contract().ServiceRequests()) {
auto packet = service_manager_.GetServicePacket(request.Service()); auto packet = service_manager_.GetServicePacket(request.Service());
if (!packet.IsEmpty()) continue; if (!packet.IsEmpty()) continue;
auto packet_or = request.Service().CreateDefaultObject(); absl::StatusOr<Packet> packet_or;
if (allow_service_default_initialization_) {
packet_or = request.Service().CreateDefaultObject();
} else {
packet_or = absl::FailedPreconditionError(
"Service default initialization is disallowed.");
}
if (packet_or.ok()) { if (packet_or.ok()) {
MP_RETURN_IF_ERROR(service_manager_.SetServicePacket( MP_RETURN_IF_ERROR(service_manager_.SetServicePacket(
request.Service(), std::move(packet_or).value())); request.Service(), std::move(packet_or).value()));

View File

@ -405,6 +405,34 @@ class CalculatorGraph {
return service_manager_.GetServiceObject(service); return service_manager_.GetServiceObject(service);
} }
// Disallows/disables default initialization of MediaPipe graph services.
//
// IMPORTANT: MediaPipe graph serices, essentially a graph-level singletons,
// are designed in the way, so they may provide default initialization. For
// example, this allows to run OpenGL processing wihtin the graph without
// provinging a praticular OpenGL context as it can be provided by
// default-initializable `kGpuService`. (One caveat here, you may still need
// to initialize it manually to share graph context with external context.)
//
// Even if calculators require some service optionally
// (`calculator_contract->UseService(kSomeService).Optional()`), it will be
// still initialized if it allows default initialization.
//
// So far, in rare cases, this may be unwanted and strict control of what
// services are allowed in the graph can be achieved by calling this method,
// following `SetServiceObject` call for services which are allowed in the
// graph.
//
// Recommendation: do not use unless you have to (for example, default
// initialization has side effects)
//
// NOTE: must be called before `StartRun`/`Run`, where services are checked
// and can be default-initialized.
absl::Status DisallowServiceDefaultInitialization() {
allow_service_default_initialization_ = false;
return absl::OkStatus();
}
// Sets a service object, essentially a graph-level singleton, which can be // Sets a service object, essentially a graph-level singleton, which can be
// accessed by calculators and subgraphs without requiring an explicit // accessed by calculators and subgraphs without requiring an explicit
// connection. // connection.
@ -644,6 +672,9 @@ class CalculatorGraph {
// Object to manage graph services. // Object to manage graph services.
GraphServiceManager service_manager_; GraphServiceManager service_manager_;
// Indicates whether service default initialization is allowed.
bool allow_service_default_initialization_ = true;
// Vector of errors encountered while running graph. Always use RecordError() // Vector of errors encountered while running graph. Always use RecordError()
// to add an error to this vector. // to add an error to this vector.
std::vector<absl::Status> errors_ ABSL_GUARDED_BY(error_mutex_); std::vector<absl::Status> errors_ ABSL_GUARDED_BY(error_mutex_);