• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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