[bes] Fix ResultStore various ids Addresses various ResultStore RPC errors. resultstore_streamer.cc: * Set the ids in the UploadRequest instead of the resource that is being Created/Updated/Finalized. * Mangle (and cache) action_ids to conform to the API spec. * Unset action dependencies for now to avoid some RPC errors. Fuchsia-Topic: build-event-stream Bug: 369980343 Change-Id: I0a538581d3aa5cb486884a6ca73be39f5454e4f2
diff --git a/src/resultstore_streamer.cc b/src/resultstore_streamer.cc index b23ffbf..097f18b 100644 --- a/src/resultstore_streamer.cc +++ b/src/resultstore_streamer.cc
@@ -189,6 +189,14 @@ } */ +struct ResultStoreStreamer::EdgeData { + // mangled string used in UploadRequests + std::string action_id; + + // TODO: consider caching the entire UploadRequest proto, + // since the majority of fields are reused over the action's lifetime. +}; + ResultStoreStreamer::ResultStoreStreamer( const std::vector<std::string>& ninja_command, const std::string& config_string, const BuildMetadataMap& metadata, @@ -268,12 +276,30 @@ } // Get an action_id from an Edge. +// From the proto spec: +// It can be any string of up to 512 alphanumeric characters [a-zA-Z0-9_-], +// except for the reserved id '-'. static std::string edge_action_id(const Edge* edge) { // Use the primary output? // assert that there is at least one output node return edge->outputs_.front()->path(); } +const ResultStoreStreamer::EdgeData& +ResultStoreStreamer::GetEdgeData(const Edge* edge) { + // TODO: replace this with try_emplace once C++17 is supported + const auto p = edge_data_.emplace(edge, EdgeData{}); + EdgeData& value = p.first->second; + if (p.second) { + // newly inserted, so compute new values + value.action_id = edge_action_id(edge); + // mangle path separator into acceptable characters + StringSubstituteCharWithString(&value.action_id, '.', "--"); + StringSubstituteCharWithString(&value.action_id, '/', "--"); + } // else already cached + return value; +} + void ResultStoreStreamer::BuildEdgeStarted(const Edge* edge, int64_t start_time_millis) { if (out_ == nullptr) return; @@ -283,11 +309,10 @@ rspb::Action* action = req.mutable_action(); - auto* id = action->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); id->set_configuration_id(kDefaultConfigurationName); - const std::string action_id(edge_action_id(edge)); // needs to be url_encoded + const std::string& action_id = GetEdgeData(edge).action_id; id->set_action_id(action_id); action->set_name( @@ -308,6 +333,7 @@ rspb::StatusAttributes* status_attrs = action->mutable_status_attributes(); status_attrs->set_status(rspb::Status::BUILDING); + /* TODO: figure out how to use deps properly. // auto* deps = action->mutable_action_dependencies(); // iterate over edge inputs for (const auto* input : edge->inputs_) { @@ -320,6 +346,7 @@ // dep.set_label(...); // description? } + */ // auto* properties = action->mutable_properties(); @@ -337,7 +364,7 @@ ExitStatus exit_code, const std::string& output) { if (out_ == nullptr) return; - const std::string action_id(edge_action_id(edge)); + const std::string& action_id = GetEdgeData(edge).action_id; { // use initial_invocation_ in UploadRequest for batching @@ -346,8 +373,7 @@ req.set_upload_operation(rspb::UploadRequest::UploadOperation::UPDATE); rspb::Action* action = req.mutable_action(); - auto* id = action->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); id->set_configuration_id(kDefaultConfigurationName); id->set_action_id(action_id); @@ -373,8 +399,7 @@ req.set_upload_operation(rspb::UploadRequest::UploadOperation::FINALIZE); rspb::Action* action = req.mutable_action(); - auto* id = action->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); id->set_configuration_id(kDefaultConfigurationName); id->set_action_id(action_id); @@ -410,8 +435,7 @@ rspb::Configuration* configuration = req.mutable_configuration(); - auto* id = configuration->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_configuration_id(kDefaultConfigurationName); // path-formatted resource name @@ -446,8 +470,7 @@ rspb::Target* target = req.mutable_target(); - auto* id = target->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); // path-formatted resource name @@ -483,10 +506,9 @@ rspb::ConfiguredTarget* ctarget = req.mutable_configured_target(); - auto* id = ctarget->mutable_id(); - id->set_invocation_id(invocation_id()); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); - id->set_configuration_id(kDefaultTargetName); + id->set_configuration_id(kDefaultConfigurationName); // path-formatted resource name ctarget->set_name(StringFormat( @@ -532,7 +554,7 @@ update_mask->add_paths("timing.duration"); rspb::ConfiguredTarget* ctarget = req.mutable_configured_target(); - auto* id = ctarget->mutable_id(); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); id->set_configuration_id(kDefaultConfigurationName); @@ -566,7 +588,7 @@ update_mask->add_paths("timing.duration"); rspb::Target* target = req.mutable_target(); - auto* id = target->mutable_id(); + auto* id = req.mutable_id(); id->set_target_id(kDefaultTargetName); millis_to_duration(common_duration, @@ -597,7 +619,7 @@ update_mask->add_paths("status_attributes"); rspb::Configuration* config = req.mutable_configuration(); - auto* id = config->mutable_id(); + auto* id = req.mutable_id(); id->set_configuration_id(kDefaultConfigurationName); config->mutable_status_attributes()->set_status(common_status);
diff --git a/src/resultstore_streamer.h b/src/resultstore_streamer.h index d63b63a..34bf301 100644 --- a/src/resultstore_streamer.h +++ b/src/resultstore_streamer.h
@@ -84,6 +84,10 @@ typedef ::rs::google::devtools::resultstore::v2::UploadRequest UploadRequest; void PostRequest(const UploadRequest&); + struct EdgeData; + + const EdgeData& GetEdgeData(const Edge*); + private: /// Original ninja invocation command. std::vector<std::string> ninja_command_; @@ -104,6 +108,9 @@ // Output stream (should be configured un-buffered) // Not owned, so the stream object should outlive this object. OutputStream* out_ = nullptr; + + // Cache of edge-associated values, to avoid re-computation. + std::map<const Edge*, EdgeData> edge_data_; }; #endif // NINJA_RESULTSTORE_STREAMER_H_