aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/grpc/src/core/lib/resolver/resolver.h
blob: 94c4cf7af25b064cef3bf641239768b9486435ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef GRPC_SRC_CORE_LIB_RESOLVER_RESOLVER_H
#define GRPC_SRC_CORE_LIB_RESOLVER_RESOLVER_H

#include <grpc/support/port_platform.h>

#include <functional>
#include <util/generic/string.h>
#include <util/string/cast.h>

#include "y_absl/status/status.h"
#include "y_absl/status/statusor.h"

#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/resolver/server_address.h"
#include "src/core/lib/service_config/service_config.h"

extern grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount;

// Name associated with individual address, if available.
#define GRPC_ARG_ADDRESS_NAME "grpc.address_name"

namespace grpc_core {

/// Interface for name resolution.
///
/// This interface is designed to support both push-based and pull-based
/// mechanisms.  A push-based mechanism is one where the resolver will
/// subscribe to updates for a given name, and the name service will
/// proactively send new data to the resolver whenever the data associated
/// with the name changes.  A pull-based mechanism is one where the resolver
/// needs to query the name service again to get updated information (e.g.,
/// DNS).
///
/// Note: All methods with a "Locked" suffix must be called from the
/// work_serializer passed to the constructor.
class Resolver : public InternallyRefCounted<Resolver> {
 public:
  /// Results returned by the resolver.
  struct Result {
    /// A list of addresses, or an error.
    y_absl::StatusOr<ServerAddressList> addresses;
    /// A service config, or an error.
    y_absl::StatusOr<RefCountedPtr<ServiceConfig>> service_config = nullptr;
    /// An optional human-readable note describing context about the resolution,
    /// to be passed along to the LB policy for inclusion in RPC failure status
    /// messages in cases where neither \a addresses nor \a service_config
    /// has a non-OK status.  For example, a resolver that returns an empty
    /// address list but a valid service config may set to this to something
    /// like "no DNS entries found for <name>".
    TString resolution_note;
    // TODO(roth): Before making this a public API, figure out a way to
    // avoid exposing channel args this way.
    ChannelArgs args;
    // If non-null, this callback will be invoked when the LB policy has
    // processed the result.  The status value passed to the callback
    // indicates whether the LB policy accepted the update.  For polling
    // resolvers, if the reported status is non-OK, then the resolver
    // should put itself into backoff to retry the resolution later.
    // The resolver impl must not call ResultHandler::ReportResult()
    // again until after this callback has been invoked.
    // The callback will be invoked within the channel's WorkSerializer.
    // It may or may not be invoked before ResultHandler::ReportResult()
    // returns, which is why it's a separate callback.
    std::function<void(y_absl::Status)> result_health_callback;
  };

  /// A proxy object used by the resolver to return results to the
  /// client channel.
  class ResultHandler {
   public:
    virtual ~ResultHandler() {}

    /// Reports a result to the channel.
    virtual void ReportResult(Result result) = 0;  // NOLINT
  };

  // Not copyable nor movable.
  Resolver(const Resolver&) = delete;
  Resolver& operator=(const Resolver&) = delete;
  ~Resolver() override = default;

  /// Starts resolving.
  virtual void StartLocked() = 0;

  /// Asks the resolver to obtain an updated resolver result, if
  /// applicable.
  ///
  /// This is useful for pull-based implementations to decide when to
  /// re-resolve.  However, the implementation is not required to
  /// re-resolve immediately upon receiving this call; it may instead
  /// elect to delay based on some configured minimum time between
  /// queries, to avoid hammering the name service with queries.
  ///
  /// For push-based implementations, this may be a no-op.
  ///
  /// Note: Implementations must not invoke any method on the
  /// ResultHandler from within this call.
  virtual void RequestReresolutionLocked() {}

  /// Resets the re-resolution backoff, if any.
  /// This needs to be implemented only by pull-based implementations;
  /// for push-based implementations, it will be a no-op.
  virtual void ResetBackoffLocked() {}

  // Note: This must be invoked while holding the work_serializer.
  void Orphan() override {
    ShutdownLocked();
    Unref();
  }

 protected:
  Resolver();

  /// Shuts down the resolver.
  virtual void ShutdownLocked() = 0;
};

}  // namespace grpc_core

#endif  // GRPC_SRC_CORE_LIB_RESOLVER_RESOLVER_H