Home | History | Annotate | Download | only in client_channel
      1 /*
      2  *
      3  * Copyright 2015 gRPC authors.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  */
     18 
     19 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
     20 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
     21 
     22 #include <grpc/support/port_platform.h>
     23 
     24 #include <grpc/impl/codegen/grpc_types.h>
     25 
     26 #include "src/core/lib/gprpp/abstract.h"
     27 #include "src/core/lib/gprpp/orphanable.h"
     28 #include "src/core/lib/iomgr/combiner.h"
     29 #include "src/core/lib/iomgr/iomgr.h"
     30 
     31 extern grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount;
     32 
     33 namespace grpc_core {
     34 
     35 /// Interface for name resolution.
     36 ///
     37 /// This interface is designed to support both push-based and pull-based
     38 /// mechanisms.  A push-based mechanism is one where the resolver will
     39 /// subscribe to updates for a given name, and the name service will
     40 /// proactively send new data to the resolver whenever the data associated
     41 /// with the name changes.  A pull-based mechanism is one where the resolver
     42 /// needs to query the name service again to get updated information (e.g.,
     43 /// DNS).
     44 ///
     45 /// Note: All methods with a "Locked" suffix must be called from the
     46 /// combiner passed to the constructor.
     47 class Resolver : public InternallyRefCountedWithTracing<Resolver> {
     48  public:
     49   // Not copyable nor movable.
     50   Resolver(const Resolver&) = delete;
     51   Resolver& operator=(const Resolver&) = delete;
     52 
     53   /// Requests a callback when a new result becomes available.
     54   /// When the new result is available, sets \a *result to the new result
     55   /// and schedules \a on_complete for execution.
     56   /// Upon transient failure, sets \a *result to nullptr and schedules
     57   /// \a on_complete with no error.
     58   /// If resolution is fatally broken, sets \a *result to nullptr and
     59   /// schedules \a on_complete with an error.
     60   /// TODO(roth): When we have time, improve the way this API represents
     61   /// transient failure vs. shutdown.
     62   ///
     63   /// Note that the client channel will almost always have a request
     64   /// to \a NextLocked() pending.  When it gets the callback, it will
     65   /// process the new result and then immediately make another call to
     66   /// \a NextLocked().  This allows push-based resolvers to provide new
     67   /// data as soon as it becomes available.
     68   virtual void NextLocked(grpc_channel_args** result,
     69                           grpc_closure* on_complete) GRPC_ABSTRACT;
     70 
     71   /// Asks the resolver to obtain an updated resolver result, if
     72   /// applicable.
     73   ///
     74   /// This is useful for pull-based implementations to decide when to
     75   /// re-resolve.  However, the implementation is not required to
     76   /// re-resolve immediately upon receiving this call; it may instead
     77   /// elect to delay based on some configured minimum time between
     78   /// queries, to avoid hammering the name service with queries.
     79   ///
     80   /// For push-based implementations, this may be a no-op.
     81   ///
     82   /// If this causes new data to become available, then the currently
     83   /// pending call to \a NextLocked() will return the new result.
     84   virtual void RequestReresolutionLocked() {}
     85 
     86   /// Resets the re-resolution backoff, if any.
     87   /// This needs to be implemented only by pull-based implementations;
     88   /// for push-based implementations, it will be a no-op.
     89   /// TODO(roth): Pull the backoff code out of resolver and into
     90   /// client_channel, so that it can be shared across resolver
     91   /// implementations.  At that point, this method can go away.
     92   virtual void ResetBackoffLocked() {}
     93 
     94   void Orphan() override {
     95     // Invoke ShutdownAndUnrefLocked() inside of the combiner.
     96     GRPC_CLOSURE_SCHED(
     97         GRPC_CLOSURE_CREATE(&Resolver::ShutdownAndUnrefLocked, this,
     98                             grpc_combiner_scheduler(combiner_)),
     99         GRPC_ERROR_NONE);
    100   }
    101 
    102   GRPC_ABSTRACT_BASE_CLASS
    103 
    104  protected:
    105   GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
    106 
    107   /// Does NOT take ownership of the reference to \a combiner.
    108   // TODO(roth): Once we have a C++-like interface for combiners, this
    109   // API should change to take a RefCountedPtr<>, so that we always take
    110   // ownership of a new ref.
    111   explicit Resolver(grpc_combiner* combiner);
    112 
    113   virtual ~Resolver();
    114 
    115   /// Shuts down the resolver.  If there is a pending call to
    116   /// NextLocked(), the callback will be scheduled with an error.
    117   virtual void ShutdownLocked() GRPC_ABSTRACT;
    118 
    119   grpc_combiner* combiner() const { return combiner_; }
    120 
    121  private:
    122   static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) {
    123     Resolver* resolver = static_cast<Resolver*>(arg);
    124     resolver->ShutdownLocked();
    125     resolver->Unref();
    126   }
    127 
    128   grpc_combiner* combiner_;
    129 };
    130 
    131 }  // namespace grpc_core
    132 
    133 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H */
    134