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