-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Title: AsyncClient returned by httpAsyncClientForCluster() does not follow lb_policy defined for cluster
Symptom:
LB Policy configured on a test cluster is RING_HASH, and I observed it was honoured by all calls going through HTTP Connection manager.
But any Async call sent using AsyncClient returned by httpAsyncClientForCluster() from a filter is not following the same LB policy. Is this the expected behavior?
Description:
Here is what is causing the problem:
In file upstream/cluster_manager_impl.cc the constructor of struct ClusterEntry is called for each cluster defined in the config when envoy starts up.
In its initializer list it invokes the constructor of Http::AsyncClientImpl to create http_async_client_ for the cluster. http_async_client_ is returned by httpAsyncClientForCluster() and is used for making Async calls.
Http::AsyncClientImpl creates AsyncStreamImpl which creates a mock Router::ProdFilter router_ and sets a bunch of mock objects on it. One of the mock objects is struct RouteEntryImpl which defines const Router::HashPolicy* hashPolicy() const override { return nullptr; }.
During an async call, when upstream/thread_aware_lb_impl.cc chooseHost() is called, it tries to computeHashKey() but in the absence a HashPolicy, it does this:
const uint64_t h = hash ? hash.value() : random_.random();
Do you think there a way to make async calls start following the lb_policy for the cluster?