A workaround for ring hash on channel id to randomize the channel id (#28986)

* A workaround for ring hash on channel id to randomize the channel id
(ref to xds_resolver) used.

* using absl random functions.
pull/28973/head^2
donnadionne 3 years ago committed by GitHub
parent ac22280779
commit 315dfb17e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      BUILD
  2. 17
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc

@ -3568,6 +3568,7 @@ grpc_cc_library(
external_deps = [
"xxhash",
"re2",
"absl/random",
"absl/strings",
],
language = "c++",

@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h>
#include "absl/random/random.h"
#include "absl/strings/match.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_replace.h"
@ -81,7 +82,8 @@ class XdsResolver : public Resolver {
args_(grpc_channel_args_copy(args.args)),
interested_parties_(args.pollset_set),
uri_(std::move(args.uri)),
data_plane_authority_(GetDataPlaneAuthority(*args.args, uri_)) {
data_plane_authority_(GetDataPlaneAuthority(*args.args, uri_)),
channel_id_(absl::Uniform<uint64_t>(absl::BitGen())) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
gpr_log(
GPR_INFO,
@ -309,6 +311,7 @@ class XdsResolver : public Resolver {
absl::StatusOr<RefCountedPtr<ServiceConfig>> CreateServiceConfig();
void GenerateResult();
void MaybeRemoveUnusedClusters();
uint64_t channel_id() const { return channel_id_; }
std::shared_ptr<WorkSerializer> work_serializer_;
std::unique_ptr<ResultHandler> result_handler_;
@ -318,6 +321,7 @@ class XdsResolver : public Resolver {
RefCountedPtr<XdsClient> xds_client_;
std::string lds_resource_name_;
std::string data_plane_authority_;
uint64_t channel_id_;
ListenerWatcher* listener_watcher_ = nullptr;
// This will not contain the RouteConfiguration, even if it comes with the
@ -652,8 +656,7 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
new_hash = HeaderHashHelper(hash_policy, args.initial_metadata);
break;
case XdsRouteConfigResource::Route::RouteAction::HashPolicy::CHANNEL_ID:
new_hash =
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(resolver_.get()));
new_hash = resolver_->channel_id();
break;
default:
GPR_ASSERT(0);
@ -672,13 +675,7 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
}
}
if (!hash.has_value()) {
// If there is no hash, we just choose a random value as a default.
// We cannot directly use the result of rand() as the hash value,
// since it is a 32-bit number and not a 64-bit number and will
// therefore not be evenly distributed.
uint32_t upper = rand();
uint32_t lower = rand();
hash = (static_cast<uint64_t>(upper) << 32) | lower;
hash = absl::Uniform<uint64_t>(absl::BitGen());
}
CallConfig call_config;
if (method_config != nullptr) {

Loading…
Cancel
Save