fake_resolver.cc
Go to the documentation of this file.
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 // This is similar to the sockaddr resolver, except that it supports a
18 // bunch of query args that are useful for dependency injection in tests.
19 
21 
23 
24 #include <memory>
25 #include <utility>
26 
27 #include "absl/memory/memory.h"
28 #include "absl/status/status.h"
29 #include "absl/status/statusor.h"
30 #include "absl/strings/string_view.h"
31 
32 #include <grpc/support/log.h>
33 
45 
46 namespace grpc_core {
47 
48 // This cannot be in an anonymous namespace, because it is a friend of
49 // FakeResolverResponseGenerator.
50 class FakeResolver : public Resolver {
51  public:
52  explicit FakeResolver(ResolverArgs args);
53 
54  void StartLocked() override;
55 
56  void RequestReresolutionLocked() override;
57 
58  private:
61 
62  ~FakeResolver() override;
63 
64  void ShutdownLocked() override;
65 
66  void MaybeSendResultLocked();
67 
69 
70  // passed-in parameters
72  std::shared_ptr<WorkSerializer> work_serializer_;
73  std::unique_ptr<ResultHandler> result_handler_;
75  // If has_next_result_ is true, next_result_ is the next resolution result
76  // to be returned.
77  bool has_next_result_ = false;
79  // Result to use for the pretended re-resolution in
80  // RequestReresolutionLocked().
83  // True after the call to StartLocked().
84  bool started_ = false;
85  // True after the call to ShutdownLocked().
86  bool shutdown_ = false;
87  // if true, return failure
88  bool return_failure_ = false;
89  // pending re-resolution
91 };
92 
94  : work_serializer_(std::move(args.work_serializer)),
95  result_handler_(std::move(args.result_handler)),
97  FakeResolverResponseGenerator::GetFromArgs(args.args)) {
98  // Channels sharing the same subchannels may have different resolver response
99  // generators. If we don't remove this arg, subchannel pool will create new
100  // subchannels for the same address instead of reusing existing ones because
101  // of different values of this channel arg.
102  const char* args_to_remove[] = {GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR};
104  args.args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove));
105  if (response_generator_ != nullptr) {
106  response_generator_->SetFakeResolver(Ref());
107  }
108 }
109 
111 
113  started_ = true;
115 }
116 
120  has_next_result_ = true;
121  // Return the result in a different closure, so that we don't call
122  // back into the LB policy while it's still processing the previous
123  // update.
126  Ref().release(); // ref held by closure
127  work_serializer_->Run([this]() { ReturnReresolutionResult(); },
129  }
130  }
131 }
132 
134  shutdown_ = true;
135  if (response_generator_ != nullptr) {
136  response_generator_->SetFakeResolver(nullptr);
137  response_generator_.reset();
138  }
139 }
140 
142  if (!started_ || shutdown_) return;
143  if (return_failure_) {
144  // TODO(roth): Change resolver result generator to be able to inject
145  // the error to be returned and to be able to independently set errors
146  // for addresses and service config.
147  Result result;
148  result.addresses = absl::UnavailableError("Resolver transient failure");
149  result.service_config = result.addresses.status();
151  result_handler_->ReportResult(std::move(result));
152  return_failure_ = false;
153  } else if (has_next_result_) {
154  // When both next_results_ and channel_args_ contain an arg with the same
155  // name, only the one in next_results_ will be kept since next_results_ is
156  // before channel_args_.
157  grpc_channel_args* new_args =
160  next_result_.args = new_args;
161  result_handler_->ReportResult(std::move(next_result_));
162  has_next_result_ = false;
163  }
164 }
165 
169  Unref();
170 }
171 
173  public:
176  bool has_result = false,
177  bool immediate = true)
178  : resolver_(std::move(resolver)),
179  result_(std::move(result)),
180  has_result_(has_result),
181  immediate_(immediate) {}
182  void SetResponseLocked();
184  void SetFailureLocked();
185 
186  private:
191 };
192 
193 // Deletes object when done
195  if (!resolver_->shutdown_) {
196  resolver_->reresolution_result_ = std::move(result_);
197  resolver_->has_reresolution_result_ = has_result_;
198  }
199  delete this;
200 }
201 
202 // Deletes object when done
204  if (!resolver_->shutdown_) {
205  resolver_->next_result_ = std::move(result_);
206  resolver_->has_next_result_ = true;
207  resolver_->MaybeSendResultLocked();
208  }
209  delete this;
210 }
211 
212 // Deletes object when done
214  if (!resolver_->shutdown_) {
215  resolver_->return_failure_ = true;
216  if (immediate_) resolver_->MaybeSendResultLocked();
217  }
218  delete this;
219 }
220 
221 //
222 // FakeResolverResponseGenerator
223 //
224 
226 
228 
231  {
232  MutexLock lock(&mu_);
233  if (resolver_ == nullptr) {
234  has_result_ = true;
235  result_ = std::move(result);
236  return;
237  }
238  resolver = resolver_->Ref();
239  }
242  resolver->work_serializer_->Run([arg]() { arg->SetResponseLocked(); },
244 }
245 
249  {
250  MutexLock lock(&mu_);
251  GPR_ASSERT(resolver_ != nullptr);
252  resolver = resolver_->Ref();
253  }
255  resolver, std::move(result), true /* has_result */);
256  resolver->work_serializer_->Run(
257  [arg]() { arg->SetReresolutionResponseLocked(); }, DEBUG_LOCATION);
258 }
259 
262  {
263  MutexLock lock(&mu_);
264  GPR_ASSERT(resolver_ != nullptr);
265  resolver = resolver_->Ref();
266  }
269  resolver->work_serializer_->Run(
270  [arg]() { arg->SetReresolutionResponseLocked(); }, DEBUG_LOCATION);
271 }
272 
275  {
276  MutexLock lock(&mu_);
277  GPR_ASSERT(resolver_ != nullptr);
278  resolver = resolver_->Ref();
279  }
282  resolver->work_serializer_->Run([arg]() { arg->SetFailureLocked(); },
284 }
285 
288  {
289  MutexLock lock(&mu_);
290  GPR_ASSERT(resolver_ != nullptr);
291  resolver = resolver_->Ref();
292  }
294  resolver, Resolver::Result(), false /* has_result */,
295  false /* immediate */);
296  resolver->work_serializer_->Run([arg]() { arg->SetFailureLocked(); },
298 }
299 
301  RefCountedPtr<FakeResolver> resolver) {
302  MutexLock lock(&mu_);
303  resolver_ = std::move(resolver);
304  if (resolver_ == nullptr) return;
305  if (has_result_) {
308  resolver_->work_serializer_->Run([arg]() { arg->SetResponseLocked(); },
310  has_result_ = false;
311  }
312 }
313 
314 namespace {
315 
316 void* ResponseGeneratorChannelArgCopy(void* p) {
317  auto* generator = static_cast<FakeResolverResponseGenerator*>(p);
318  generator->Ref().release();
319  return p;
320 }
321 
322 void ResponseGeneratorChannelArgDestroy(void* p) {
323  auto* generator = static_cast<FakeResolverResponseGenerator*>(p);
324  generator->Unref();
325 }
326 
327 int ResponseGeneratorChannelArgCmp(void* a, void* b) {
328  return QsortCompare(a, b);
329 }
330 
331 } // namespace
332 
335  ResponseGeneratorChannelArgCopy, ResponseGeneratorChannelArgDestroy,
336  ResponseGeneratorChannelArgCmp};
337 
339  FakeResolverResponseGenerator* generator) {
341  const_cast<char*>(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR), generator,
343 }
344 
347  auto* response_generator =
348  grpc_channel_args_find_pointer<FakeResolverResponseGenerator>(
350  if (response_generator == nullptr) return nullptr;
351  return response_generator->Ref();
352 }
353 
354 //
355 // Factory
356 //
357 
358 namespace {
359 
360 class FakeResolverFactory : public ResolverFactory {
361  public:
362  absl::string_view scheme() const override { return "fake"; }
363 
364  bool IsValidUri(const URI& /*uri*/) const override { return true; }
365 
366  OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
367  return MakeOrphanable<FakeResolver>(std::move(args));
368  }
369 };
370 
371 } // namespace
372 
374  builder->resolver_registry()->RegisterResolverFactory(
375  absl::make_unique<FakeResolverFactory>());
376 }
377 
378 } // namespace grpc_core
379 
grpc_arg
Definition: grpc_types.h:103
grpc_core::Resolver::Result::args
const grpc_channel_args * args
Definition: resolver/resolver.h:70
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
orphanable.h
log.h
grpc_core::FakeResolver::channel_args_
grpc_channel_args * channel_args_
Definition: fake_resolver.cc:71
core_configuration.h
grpc_core::FakeResolver::started_
bool started_
Definition: fake_resolver.cc:84
grpc_core::FakeResolver::reresolution_result_
Result reresolution_result_
Definition: fake_resolver.cc:82
grpc_channel_args_copy_and_remove
grpc_channel_args * grpc_channel_args_copy_and_remove(const grpc_channel_args *src, const char **to_remove, size_t num_to_remove)
Definition: channel_args.cc:231
grpc_core::FakeResolverResponseGenerator::SetResponse
void SetResponse(Resolver::Result result)
Definition: fake_resolver.cc:229
grpc_core::FakeResolver::ShutdownLocked
void ShutdownLocked() override
Shuts down the resolver.
Definition: fake_resolver.cc:133
grpc_core::FakeResolver::work_serializer_
std::shared_ptr< WorkSerializer > work_serializer_
Definition: fake_resolver.cc:72
grpc_core::InternallyRefCounted< Resolver >::Unref
void Unref()
Definition: orphanable.h:100
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::CoreConfiguration::Builder
Definition: core_configuration.h:41
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
useful.h
fake_resolver.h
grpc_core::FakeResolver::RequestReresolutionLocked
void RequestReresolutionLocked() override
Definition: fake_resolver.cc:117
grpc_core::FakeResolverResponseSetter::SetReresolutionResponseLocked
void SetReresolutionResponseLocked()
Definition: fake_resolver.cc:194
grpc_core::FakeResolverResponseGenerator::mu_
Mutex mu_
Definition: fake_resolver.h:91
grpc_arg_pointer_vtable
Definition: grpc_types.h:85
grpc_channel_args
Definition: grpc_types.h:132
grpc_core::FakeResolver::next_result_
Result next_result_
Definition: fake_resolver.cc:78
grpc_core::FakeResolverResponseSetter::resolver_
RefCountedPtr< FakeResolver > resolver_
Definition: fake_resolver.cc:187
grpc_core::FakeResolver::response_generator_
RefCountedPtr< FakeResolverResponseGenerator > response_generator_
Definition: fake_resolver.cc:74
grpc_core::FakeResolverResponseGenerator::SetFailureOnReresolution
void SetFailureOnReresolution()
Definition: fake_resolver.cc:286
grpc_core::FakeResolverResponseGenerator::SetFailure
void SetFailure()
Definition: fake_resolver.cc:273
grpc_core::FakeResolverResponseSetter::SetResponseLocked
void SetResponseLocked()
Definition: fake_resolver.cc:203
resolver_factory.h
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
grpc_core::FakeResolver::has_reresolution_result_
bool has_reresolution_result_
Definition: fake_resolver.cc:81
grpc_core::FakeResolver::MaybeSendResultLocked
void MaybeSendResultLocked()
Definition: fake_resolver.cc:141
grpc_core::FakeResolverResponseGenerator::kChannelArgPointerVtable
static const grpc_arg_pointer_vtable kChannelArgPointerVtable
Definition: fake_resolver.h:49
grpc_core::FakeResolver::~FakeResolver
~FakeResolver() override
Definition: fake_resolver.cc:110
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
grpc_core::FakeResolverResponseGenerator::~FakeResolverResponseGenerator
~FakeResolverResponseGenerator() override
Definition: fake_resolver.cc:227
grpc_core::FakeResolver::shutdown_
bool shutdown_
Definition: fake_resolver.cc:86
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
response_generator_
RefCountedPtr< FakeResolverResponseGenerator > response_generator_
Definition: grpclb.cc:522
grpc_core::FakeResolver::result_handler_
std::unique_ptr< ResultHandler > result_handler_
Definition: fake_resolver.cc:73
grpc_core::Resolver
Definition: resolver/resolver.h:53
grpc_core::FakeResolverResponseGenerator::GetFromArgs
static RefCountedPtr< FakeResolverResponseGenerator > GetFromArgs(const grpc_channel_args *args)
Definition: fake_resolver.cc:346
grpc_core::InternallyRefCounted< Resolver >::Ref
RefCountedPtr< Resolver > Ref() GRPC_MUST_USE_RESULT
Definition: orphanable.h:90
work_serializer.h
grpc_core::FakeResolverResponseGenerator::SetFakeResolver
void SetFakeResolver(RefCountedPtr< FakeResolver > resolver)
Definition: fake_resolver.cc:300
grpc_core::Resolver::Result
Results returned by the resolver.
Definition: resolver/resolver.h:56
grpc_channel_args_union
grpc_channel_args * grpc_channel_args_union(const grpc_channel_args *a, const grpc_channel_args *b)
Definition: channel_args.cc:289
grpc_core::RegisterFakeResolver
void RegisterFakeResolver(CoreConfiguration::Builder *builder)
Definition: fake_resolver.cc:373
GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR
Definition: fake_resolver.h:31
grpc_core::ResolverArgs
Definition: resolver_factory.h:41
grpc_channel_args_destroy
void grpc_channel_args_destroy(grpc_channel_args *a)
Definition: channel_args.cc:360
arg
Definition: cmdline.cc:40
server_address.h
grpc_channel_args_copy
grpc_channel_args * grpc_channel_args_copy(const grpc_channel_args *src)
Definition: channel_args.cc:285
grpc_core::FakeResolverResponseSetter::immediate_
bool immediate_
Definition: fake_resolver.cc:190
grpc_core::FakeResolverResponseGenerator::SetReresolutionResponse
void SetReresolutionResponse(Resolver::Result result)
Definition: fake_resolver.cc:246
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
grpc_core::FakeResolver::reresolution_closure_pending_
bool reresolution_closure_pending_
Definition: fake_resolver.cc:90
result_handler_
std::unique_ptr< ResultHandler > result_handler_
Definition: sockaddr_resolver.cc:59
resolver_registry.h
grpc_core::FakeResolverResponseSetter
Definition: fake_resolver.cc:172
grpc_core::FakeResolverResponseSetter::FakeResolverResponseSetter
FakeResolverResponseSetter(RefCountedPtr< FakeResolver > resolver, Resolver::Result result, bool has_result=false, bool immediate=true)
Definition: fake_resolver.cc:174
GPR_ARRAY_SIZE
#define GPR_ARRAY_SIZE(array)
Definition: useful.h:129
debug_location.h
grpc_core::FakeResolverResponseSetter::SetFailureLocked
void SetFailureLocked()
Definition: fake_resolver.cc:213
grpc_core::FakeResolver
Definition: fake_resolver.cc:50
grpc_core::QsortCompare
int QsortCompare(const T &a, const T &b)
Definition: useful.h:95
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_resolver_fake_shutdown
void grpc_resolver_fake_shutdown()
Definition: fake_resolver.cc:380
resolver_
OrphanablePtr< Resolver > resolver_
Definition: xds_cluster_resolver.cc:291
absl::UnavailableError
Status UnavailableError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:375
grpc_core::FakeResolverResponseSetter::result_
Resolver::Result result_
Definition: fake_resolver.cc:188
grpc_core::FakeResolver::FakeResolver
FakeResolver(ResolverArgs args)
Definition: fake_resolver.cc:93
channel_args.h
grpc_core::FakeResolver::ReturnReresolutionResult
void ReturnReresolutionResult()
Definition: fake_resolver.cc:166
service_config.h
grpc_core::FakeResolverResponseGenerator::UnsetReresolutionResponse
void UnsetReresolutionResponse()
Definition: fake_resolver.cc:260
work_serializer_
std::shared_ptr< WorkSerializer > work_serializer_
Definition: google_c2p_resolver.cc:134
grpc_core::FakeResolverResponseGenerator::MakeChannelArg
static grpc_arg MakeChannelArg(FakeResolverResponseGenerator *generator)
Definition: fake_resolver.cc:338
grpc_core::FakeResolver::has_next_result_
bool has_next_result_
Definition: fake_resolver.cc:77
uri_parser.h
grpc_core::FakeResolverResponseGenerator
Definition: fake_resolver.h:46
grpc_core::FakeResolverResponseGenerator::FakeResolverResponseGenerator
FakeResolverResponseGenerator()
Definition: fake_resolver.cc:225
grpc_core::FakeResolver::return_failure_
bool return_failure_
Definition: fake_resolver.cc:88
grpc_channel_arg_pointer_create
grpc_arg grpc_channel_arg_pointer_create(char *name, void *value, const grpc_arg_pointer_vtable *vtable)
Definition: channel_args.cc:492
grpc_core::ResolverFactory
Definition: resolver_factory.h:54
grpc_core::RefCounted::Ref
RefCountedPtr< Child > Ref() GRPC_MUST_USE_RESULT
Definition: ref_counted.h:287
grpc_core::FakeResolver::StartLocked
void StartLocked() override
Starts resolving.
Definition: fake_resolver.cc:112
port_platform.h
grpc_core::FakeResolverResponseSetter::has_result_
bool has_result_
Definition: fake_resolver.cc:189


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:22