diff --git a/doc/service_config.md b/doc/service_config.md index 57f5e1989e8..6312cda7f62 100644 --- a/doc/service_config.md +++ b/doc/service_config.md @@ -62,12 +62,12 @@ DNS](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md). Here is an example service config in protobuf form: -``` +```textproto { - // Use round_robin LB policy. + # Use round_robin LB policy. load_balancing_config: { round_robin: {} } - // This method config applies to method "foo/bar" and to all methods - // of service "baz". + # This method config applies to method "foo/bar" and to all methods + # of service "baz". method_config: { name: { service: "foo" @@ -76,7 +76,7 @@ Here is an example service config in protobuf form: name: { service: "baz" } - // Default timeout for matching methods. + # Default timeout for matching methods. timeout: { seconds: 1 nanos: 1 @@ -87,7 +87,7 @@ Here is an example service config in protobuf form: Here is the same example service config in JSON form: -``` +```json { "loadBalancingConfig": [ { "round_robin": {} } ], "methodConfig": [ diff --git a/gRPC.podspec b/gRPC.podspec index 2be61d98270..120a23ffcbc 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -32,6 +32,8 @@ Pod::Spec.new do |s| :tag => "v#{version}", } + s.resource = 'src/objective-c/PrivacyInfo.xcprivacy' + name = 'GRPCClient' s.module_name = name s.header_dir = name diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 851dbd15a38..532562389fd 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -16,3 +16,4 @@ xds-protos==0.0.11 opencensus==0.10.0 opencensus-ext-stackdriver==0.8.0 absl-py==1.4.0 +googleapis-common-protos==1.61.0 diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 037e2b59e0b..b2d1be8fea5 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -839,9 +839,9 @@ void Server::Start() { if (unregistered_request_matcher_ == nullptr) { unregistered_request_matcher_ = make_real_request_matcher(); } - for (std::unique_ptr& rm : registered_methods_) { - if (rm->matcher == nullptr) { - rm->matcher = make_real_request_matcher(); + for (auto& rm : registered_methods_) { + if (rm.second->matcher == nullptr) { + rm.second->matcher = make_real_request_matcher(); } } { @@ -928,20 +928,11 @@ void Server::RegisterCompletionQueue(grpc_completion_queue* cq) { cqs_.push_back(cq); } -namespace { - -bool streq(const std::string& a, const char* b) { - return (a.empty() && b == nullptr) || - ((b != nullptr) && !strcmp(a.c_str(), b)); -} - -} // namespace - Server::RegisteredMethod* Server::RegisterMethod( const char* method, const char* host, grpc_server_register_method_payload_handling payload_handling, uint32_t flags) { - if (IsRegisteredMethodsMapEnabled() && started_) { + if (started_) { Crash("Attempting to register method after server started"); } @@ -950,21 +941,21 @@ Server::RegisteredMethod* Server::RegisterMethod( "grpc_server_register_method method string cannot be NULL"); return nullptr; } - for (std::unique_ptr& m : registered_methods_) { - if (streq(m->method, method) && streq(m->host, host)) { - gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method, - host ? host : "*"); - return nullptr; - } + auto key = std::make_pair(host ? host : "", method); + if (registered_methods_.find(key) != registered_methods_.end()) { + gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method, + host ? host : "*"); + return nullptr; } if (flags != 0) { gpr_log(GPR_ERROR, "grpc_server_register_method invalid flags 0x%08x", flags); return nullptr; } - registered_methods_.emplace_back(std::make_unique( - method, host, payload_handling, flags)); - return registered_methods_.back().get(); + auto it = registered_methods_.emplace( + key, std::make_unique(method, host, payload_handling, + flags)); + return it.first->second.get(); } void Server::DoneRequestEvent(void* req, grpc_cq_completion* /*c*/) { @@ -1015,9 +1006,9 @@ void Server::KillPendingWorkLocked(grpc_error_handle error) { if (started_) { unregistered_request_matcher_->KillRequests(error); unregistered_request_matcher_->ZombifyPending(); - for (std::unique_ptr& rm : registered_methods_) { - rm->matcher->KillRequests(error); - rm->matcher->ZombifyPending(); + for (auto& rm : registered_methods_) { + rm.second->matcher->KillRequests(error); + rm.second->matcher->ZombifyPending(); } } } @@ -1252,7 +1243,6 @@ class Server::ChannelData::ConnectivityWatcher // Server::ChannelData::~ChannelData() { - old_registered_methods_.reset(); if (server_ != nullptr) { if (server_->channelz_node_ != nullptr && channelz_socket_uuid_ != 0) { server_->channelz_node_->RemoveChildSocket(channelz_socket_uuid_); @@ -1276,50 +1266,6 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, channel_ = channel; cq_idx_ = cq_idx; channelz_socket_uuid_ = channelz_socket_uuid; - // Build a lookup table phrased in terms of mdstr's in this channels context - // to quickly find registered methods. - size_t num_registered_methods = server_->registered_methods_.size(); - if (!IsRegisteredMethodsMapEnabled() && num_registered_methods > 0) { - uint32_t max_probes = 0; - size_t slots = 2 * num_registered_methods; - old_registered_methods_ = - std::make_unique>(slots); - for (std::unique_ptr& rm : server_->registered_methods_) { - Slice host; - Slice method = Slice::FromExternalString(rm->method); - const bool has_host = !rm->host.empty(); - if (has_host) { - host = Slice::FromExternalString(rm->host); - } - uint32_t hash = MixHash32(has_host ? host.Hash() : 0, method.Hash()); - uint32_t probes = 0; - for (probes = 0; (*old_registered_methods_)[(hash + probes) % slots] - .server_registered_method != nullptr; - probes++) { - } - if (probes > max_probes) max_probes = probes; - ChannelRegisteredMethod* crm = - &(*old_registered_methods_)[(hash + probes) % slots]; - crm->server_registered_method = rm.get(); - crm->flags = rm->flags; - crm->has_host = has_host; - if (has_host) { - crm->host = std::move(host); - } - crm->method = std::move(method); - } - GPR_ASSERT(slots <= UINT32_MAX); - registered_method_max_probes_ = max_probes; - } else if (IsRegisteredMethodsMapEnabled()) { - for (std::unique_ptr& rm : server_->registered_methods_) { - auto key = std::make_pair(!rm->host.empty() ? rm->host : "", rm->method); - registered_methods_.emplace( - key, std::make_unique( - rm.get(), rm->flags, /*has_host=*/!rm->host.empty(), - Slice::FromExternalString(rm->method), - Slice::FromExternalString(rm->host))); - } - } // Publish channel. { MutexLock lock(&server_->mu_global_); @@ -1345,45 +1291,17 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, transport->PerformOp(op); } -Server::ChannelRegisteredMethod* Server::ChannelData::GetRegisteredMethod( - const grpc_slice& host, const grpc_slice& path) { - if (old_registered_methods_ == nullptr) return nullptr; - // TODO(ctiller): unify these two searches - // check for an exact match with host - uint32_t hash = MixHash32(grpc_slice_hash(host), grpc_slice_hash(path)); - for (size_t i = 0; i <= registered_method_max_probes_; i++) { - ChannelRegisteredMethod* rm = &( - *old_registered_methods_)[(hash + i) % old_registered_methods_->size()]; - if (rm->server_registered_method == nullptr) break; - if (!rm->has_host) continue; - if (rm->host != host) continue; - if (rm->method != path) continue; - return rm; - } - // check for a wildcard method definition (no host set) - hash = MixHash32(0, grpc_slice_hash(path)); - for (size_t i = 0; i <= registered_method_max_probes_; i++) { - ChannelRegisteredMethod* rm = &( - *old_registered_methods_)[(hash + i) % old_registered_methods_->size()]; - if (rm->server_registered_method == nullptr) break; - if (rm->has_host) continue; - if (rm->method != path) continue; - return rm; - } - return nullptr; -} - -Server::ChannelRegisteredMethod* Server::ChannelData::GetRegisteredMethod( +Server::RegisteredMethod* Server::ChannelData::GetRegisteredMethod( const absl::string_view& host, const absl::string_view& path) { - if (registered_methods_.empty()) return nullptr; + if (server_->registered_methods_.empty()) return nullptr; // check for an exact match with host - auto it = registered_methods_.find(std::make_pair(host, path)); - if (it != registered_methods_.end()) { + auto it = server_->registered_methods_.find(std::make_pair(host, path)); + if (it != server_->registered_methods_.end()) { return it->second.get(); } // check for wildcard method definition (no host set) - it = registered_methods_.find(std::make_pair("", path)); - if (it != registered_methods_.end()) { + it = server_->registered_methods_.find(std::make_pair("", path)); + if (it != server_->registered_methods_.end()) { return it->second.get(); } return nullptr; @@ -1404,13 +1322,8 @@ void Server::ChannelData::SetRegisteredMethodOnMetadata( // Path not being set would result in an RPC error. return; } - ChannelRegisteredMethod* method; - if (!IsRegisteredMethodsMapEnabled()) { - method = GetRegisteredMethod(authority->c_slice(), path->c_slice()); - } else { - method = GetRegisteredMethod(authority->as_string_view(), - path->as_string_view()); - } + RegisteredMethod* method = + GetRegisteredMethod(authority->as_string_view(), path->as_string_view()); // insert in metadata metadata.Set(GrpcRegisteredMethod(), method); } @@ -1481,24 +1394,20 @@ ArenaPromise Server::ChannelData::MakeCallPromise( Timestamp deadline = GetContext()->deadline(); // Find request matcher. RequestMatcherInterface* matcher; - ChannelRegisteredMethod* rm = nullptr; + RegisteredMethod* rm = nullptr; if (IsRegisteredMethodLookupInTransportEnabled()) { - rm = static_cast( + rm = static_cast( call_args.client_initial_metadata->get(GrpcRegisteredMethod()) .value_or(nullptr)); } else { - if (!IsRegisteredMethodsMapEnabled()) { - rm = chand->GetRegisteredMethod(host_ptr->c_slice(), path->c_slice()); - } else { - rm = chand->GetRegisteredMethod(host_ptr->as_string_view(), - path->as_string_view()); - } + rm = chand->GetRegisteredMethod(host_ptr->as_string_view(), + path->as_string_view()); } ArenaPromise>> maybe_read_first_message([] { return NextResult(); }); if (rm != nullptr) { - matcher = rm->server_registered_method->matcher.get(); - switch (rm->server_registered_method->payload_handling) { + matcher = rm->matcher.get(); + switch (rm->payload_handling) { case GRPC_SRM_PAYLOAD_NONE: break; case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: @@ -1752,22 +1661,18 @@ void Server::CallData::StartNewRpc(grpc_call_element* elem) { grpc_server_register_method_payload_handling payload_handling = GRPC_SRM_PAYLOAD_NONE; if (path_.has_value() && host_.has_value()) { - ChannelRegisteredMethod* rm; + RegisteredMethod* rm; if (IsRegisteredMethodLookupInTransportEnabled()) { - rm = static_cast( + rm = static_cast( recv_initial_metadata_->get(GrpcRegisteredMethod()) .value_or(nullptr)); } else { - if (!IsRegisteredMethodsMapEnabled()) { - rm = chand->GetRegisteredMethod(host_->c_slice(), path_->c_slice()); - } else { - rm = chand->GetRegisteredMethod(host_->as_string_view(), - path_->as_string_view()); - } + rm = chand->GetRegisteredMethod(host_->as_string_view(), + path_->as_string_view()); } if (rm != nullptr) { - matcher_ = rm->server_registered_method->matcher.get(); - payload_handling = rm->server_registered_method->payload_handling; + matcher_ = rm->matcher.get(); + payload_handling = rm->payload_handling; } } // Start recv_message op if needed. diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 4e181c8bb37..226fb9fc132 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -211,26 +211,6 @@ class Server : public InternallyRefCounted, private: struct RequestedCall; - struct ChannelRegisteredMethod { - ChannelRegisteredMethod() = default; - ChannelRegisteredMethod(RegisteredMethod* server_registered_method_arg, - uint32_t flags_arg, bool has_host_arg, - Slice method_arg, Slice host_arg) - : server_registered_method(server_registered_method_arg), - flags(flags_arg), - has_host(has_host_arg), - method(std::move(method_arg)), - host(std::move(host_arg)) {} - - ~ChannelRegisteredMethod() = default; - - RegisteredMethod* server_registered_method = nullptr; - uint32_t flags; - bool has_host; - Slice method; - Slice host; - }; - class RequestMatcherInterface; class RealRequestMatcherFilterStack; class RealRequestMatcherPromises; @@ -251,11 +231,8 @@ class Server : public InternallyRefCounted, Channel* channel() const { return channel_.get(); } size_t cq_idx() const { return cq_idx_; } - ChannelRegisteredMethod* GetRegisteredMethod(const grpc_slice& host, - const grpc_slice& path); - - ChannelRegisteredMethod* GetRegisteredMethod(const absl::string_view& host, - const absl::string_view& path); + RegisteredMethod* GetRegisteredMethod(const absl::string_view& host, + const absl::string_view& path); // Filter vtable functions. static grpc_error_handle InitChannelElement( grpc_channel_element* elem, grpc_channel_element_args* args); @@ -274,36 +251,12 @@ class Server : public InternallyRefCounted, static void FinishDestroy(void* arg, grpc_error_handle error); - struct StringViewStringViewPairHash - : absl::flat_hash_set< - std::pair>::hasher { - using is_transparent = void; - }; - - struct StringViewStringViewPairEq - : std::equal_to> { - using is_transparent = void; - }; - RefCountedPtr server_; RefCountedPtr channel_; // The index into Server::cqs_ of the CQ used as a starting point for // where to publish new incoming calls. size_t cq_idx_; absl::optional::iterator> list_position_; - // A hash-table of the methods and hosts of the registered methods. - // TODO(vjpai): Convert this to an STL map type as opposed to a direct - // bucket implementation. (Consider performance impact, hash function to - // use, etc.) - std::unique_ptr> - old_registered_methods_; - // Map of registered methods. - absl::flat_hash_map /*host, method*/, - std::unique_ptr, - StringViewStringViewPairHash, - StringViewStringViewPairEq> - registered_methods_; - uint32_t registered_method_max_probes_; grpc_closure finish_destroy_channel_closure_; intptr_t channelz_socket_uuid_; }; @@ -412,6 +365,17 @@ class Server : public InternallyRefCounted, grpc_cq_completion completion; }; + struct StringViewStringViewPairHash + : absl::flat_hash_set< + std::pair>::hasher { + using is_transparent = void; + }; + + struct StringViewStringViewPairEq + : std::equal_to> { + using is_transparent = void; + }; + static void ListenerDestroyDone(void* arg, grpc_error_handle error); static void DoneShutdownEvent(void* server, @@ -497,7 +461,11 @@ class Server : public InternallyRefCounted, bool starting_ ABSL_GUARDED_BY(mu_global_) = false; CondVar starting_cv_; - std::vector> registered_methods_; + // Map of registered methods. + absl::flat_hash_map /*host, method*/, + std::unique_ptr, + StringViewStringViewPairHash, StringViewStringViewPairEq> + registered_methods_; // Request matcher for unregistered methods. std::unique_ptr unregistered_request_matcher_; diff --git a/src/objective-c/PrivacyInfo.xcprivacy b/src/objective-c/PrivacyInfo.xcprivacy new file mode 100644 index 00000000000..276f7610da6 --- /dev/null +++ b/src/objective-c/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index 735a0ab449c..6bba4e1aa6c 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -34,6 +34,8 @@ :tag => "v#{version}", } + s.resource = 'src/objective-c/PrivacyInfo.xcprivacy' + name = 'GRPCClient' s.module_name = name s.header_dir = name