1 // 2 // Copyright 2016 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 18 #define GRPC_SRC_CORE_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 19 20 #include <grpc/support/port_platform.h> 21 #include <stddef.h> 22 23 #include <memory> 24 #include <utility> 25 26 #include "src/core/lib/resource_quota/arena.h" 27 #include "src/core/service_config/service_config.h" 28 #include "src/core/service_config/service_config_parser.h" 29 #include "src/core/util/chunked_vector.h" 30 #include "src/core/util/down_cast.h" 31 #include "src/core/util/ref_counted_ptr.h" 32 #include "src/core/util/unique_type_name.h" 33 34 namespace grpc_core { 35 36 /// Stores the service config data associated with an individual call. 37 /// A pointer to this object is stored in the call context, so that 38 /// filters can easily access method and global parameters for the call. 39 /// 40 /// Must be accessed when holding the call combiner (legacy filter) or from 41 /// inside the activity (promise-based filter). 42 class ServiceConfigCallData { 43 public: 44 class CallAttributeInterface { 45 public: 46 virtual ~CallAttributeInterface() = default; 47 virtual UniqueTypeName type() const = 0; 48 }; 49 50 explicit ServiceConfigCallData(Arena* arena); 51 52 virtual ~ServiceConfigCallData() = default; 53 SetServiceConfig(RefCountedPtr<ServiceConfig> service_config,const ServiceConfigParser::ParsedConfigVector * method_configs)54 void SetServiceConfig( 55 RefCountedPtr<ServiceConfig> service_config, 56 const ServiceConfigParser::ParsedConfigVector* method_configs) { 57 service_config_ = std::move(service_config); 58 method_configs_ = method_configs; 59 } 60 service_config()61 ServiceConfig* service_config() { return service_config_.get(); } 62 GetMethodParsedConfig(size_t index)63 ServiceConfigParser::ParsedConfig* GetMethodParsedConfig(size_t index) const { 64 if (method_configs_ == nullptr) return nullptr; 65 return (*method_configs_)[index].get(); 66 } 67 GetGlobalParsedConfig(size_t index)68 ServiceConfigParser::ParsedConfig* GetGlobalParsedConfig(size_t index) const { 69 if (service_config_ == nullptr) return nullptr; 70 return service_config_->GetGlobalParsedConfig(index); 71 } 72 SetCallAttribute(CallAttributeInterface * value)73 void SetCallAttribute(CallAttributeInterface* value) { 74 // Overwrite existing entry if we already have one for this type. 75 for (CallAttributeInterface*& attribute : call_attributes_) { 76 if (value->type() == attribute->type()) { 77 attribute = value; 78 return; 79 } 80 } 81 // Otherwise, add a new entry. 82 call_attributes_.EmplaceBack(value); 83 } 84 85 template <typename A> GetCallAttribute()86 A* GetCallAttribute() const { 87 return DownCast<A*>(GetCallAttribute(A::TypeName())); 88 } 89 GetCallAttribute(UniqueTypeName type)90 CallAttributeInterface* GetCallAttribute(UniqueTypeName type) const { 91 for (CallAttributeInterface* attribute : call_attributes_) { 92 if (attribute->type() == type) return attribute; 93 } 94 return nullptr; 95 } 96 97 private: 98 RefCountedPtr<ServiceConfig> service_config_; 99 const ServiceConfigParser::ParsedConfigVector* method_configs_ = nullptr; 100 ChunkedVector<CallAttributeInterface*, 4> call_attributes_; 101 }; 102 103 template <> 104 struct ArenaContextType<ServiceConfigCallData> { 105 static void Destroy(ServiceConfigCallData* ptr) { 106 ptr->~ServiceConfigCallData(); 107 } 108 }; 109 110 inline ServiceConfigCallData::ServiceConfigCallData(Arena* arena) 111 : call_attributes_(arena) { 112 arena->SetContext<ServiceConfigCallData>(this); 113 } 114 115 } // namespace grpc_core 116 117 #endif // GRPC_SRC_CORE_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 118