xref: /aosp_15_r20/external/grpc-grpc/src/core/resolver/resolver.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 // Copyright 2015 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_RESOLVER_RESOLVER_H
18 #define GRPC_SRC_CORE_RESOLVER_RESOLVER_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <functional>
23 #include <string>
24 
25 #include "absl/status/status.h"
26 #include "absl/status/statusor.h"
27 
28 #include "src/core/lib/channel/channel_args.h"
29 #include "src/core/lib/debug/trace.h"
30 #include "src/core/lib/gprpp/orphanable.h"
31 #include "src/core/lib/gprpp/ref_counted_ptr.h"
32 #include "src/core/resolver/endpoint_addresses.h"
33 #include "src/core/resolver/server_address.h"  // IWYU pragma: keep
34 #include "src/core/service_config/service_config.h"
35 
36 extern grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount;
37 
38 // Name associated with individual address, if available.
39 #define GRPC_ARG_ADDRESS_NAME "grpc.address_name"
40 
41 namespace grpc_core {
42 
43 /// Interface for name resolution.
44 ///
45 /// This interface is designed to support both push-based and pull-based
46 /// mechanisms.  A push-based mechanism is one where the resolver will
47 /// subscribe to updates for a given name, and the name service will
48 /// proactively send new data to the resolver whenever the data associated
49 /// with the name changes.  A pull-based mechanism is one where the resolver
50 /// needs to query the name service again to get updated information (e.g.,
51 /// DNS).
52 ///
53 /// Note: All methods with a "Locked" suffix must be called from the
54 /// work_serializer passed to the constructor.
55 class Resolver : public InternallyRefCounted<Resolver> {
56  public:
57   /// Results returned by the resolver.
58   struct Result {
59     /// A list of endpoints, each with one or more addresses, or an error.
60     absl::StatusOr<EndpointAddressesList> addresses;
61     /// A service config, or an error.
62     absl::StatusOr<RefCountedPtr<ServiceConfig>> service_config = nullptr;
63     /// An optional human-readable note describing context about the resolution,
64     /// to be passed along to the LB policy for inclusion in RPC failure status
65     /// messages in cases where neither \a addresses nor \a service_config
66     /// has a non-OK status.  For example, a resolver that returns an empty
67     /// address list but a valid service config may set to this to something
68     /// like "no DNS entries found for <name>".
69     std::string resolution_note;
70     // TODO(roth): Before making this a public API, figure out a way to
71     // avoid exposing channel args this way.
72     ChannelArgs args;
73     // If non-null, this callback will be invoked when the LB policy has
74     // processed the result.  The status value passed to the callback
75     // indicates whether the LB policy accepted the update.  For polling
76     // resolvers, if the reported status is non-OK, then the resolver
77     // should put itself into backoff to retry the resolution later.
78     // The resolver impl must not call ResultHandler::ReportResult()
79     // again until after this callback has been invoked.
80     // The callback will be invoked within the channel's WorkSerializer.
81     // It may or may not be invoked before ResultHandler::ReportResult()
82     // returns, which is why it's a separate callback.
83     std::function<void(absl::Status)> result_health_callback;
84   };
85 
86   /// A proxy object used by the resolver to return results to the
87   /// client channel.
88   class ResultHandler {
89    public:
~ResultHandler()90     virtual ~ResultHandler() {}
91 
92     /// Reports a result to the channel.
93     virtual void ReportResult(Result result) = 0;  // NOLINT
94   };
95 
96   // Not copyable nor movable.
97   Resolver(const Resolver&) = delete;
98   Resolver& operator=(const Resolver&) = delete;
99   ~Resolver() override = default;
100 
101   /// Starts resolving.
102   virtual void StartLocked() = 0;
103 
104   /// Asks the resolver to obtain an updated resolver result, if
105   /// applicable.
106   ///
107   /// This is useful for pull-based implementations to decide when to
108   /// re-resolve.  However, the implementation is not required to
109   /// re-resolve immediately upon receiving this call; it may instead
110   /// elect to delay based on some configured minimum time between
111   /// queries, to avoid hammering the name service with queries.
112   ///
113   /// For push-based implementations, this may be a no-op.
114   ///
115   /// Note: Implementations must not invoke any method on the
116   /// ResultHandler from within this call.
RequestReresolutionLocked()117   virtual void RequestReresolutionLocked() {}
118 
119   /// Resets the re-resolution backoff, if any.
120   /// This needs to be implemented only by pull-based implementations;
121   /// for push-based implementations, it will be a no-op.
ResetBackoffLocked()122   virtual void ResetBackoffLocked() {}
123 
124   // Note: This must be invoked while holding the work_serializer.
Orphan()125   void Orphan() override {
126     ShutdownLocked();
127     Unref();
128   }
129 
130  protected:
131   Resolver();
132 
133   /// Shuts down the resolver.
134   virtual void ShutdownLocked() = 0;
135 };
136 
137 }  // namespace grpc_core
138 
139 #endif  // GRPC_SRC_CORE_RESOLVER_RESOLVER_H
140