-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simulation for load balancing logic. #127
Changes from 3 commits
9d119d2
a369c32
58c3418
eb1469a
d11aa7a
da6d9a2
f9897a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#include "common/runtime/runtime_impl.h" | ||
#include "common/upstream/load_balancer_impl.h" | ||
#include "common/upstream/upstream_impl.h" | ||
|
||
#include "test/mocks/runtime/mocks.h" | ||
#include "test/mocks/upstream/mocks.h" | ||
|
||
using testing::NiceMock; | ||
using testing::Return; | ||
|
||
namespace Upstream { | ||
|
||
static HostPtr newTestHost(const Upstream::Cluster& cluster, const std::string& url, | ||
uint32_t weight = 1, const std::string& zone = "") { | ||
return HostPtr{new HostImpl(cluster, url, false, weight, zone)}; | ||
} | ||
|
||
/** | ||
* This test is for simulation only and should not be run as part of unit tests. | ||
*/ | ||
class DISABLED_SimulationTest : public testing::Test { | ||
public: | ||
DISABLED_SimulationTest() : stats_(ClusterImplBase::generateStats("", stats_store_)) {} | ||
|
||
/** | ||
* @param originating_cluster total number of hosts in each zone in originating cluster. | ||
* @param all_destination_cluster total number of hosts in each zone in upstream cluster. | ||
* @param healthy_destination_cluster total number of healthy hosts in each zone in upstream | ||
* cluster. | ||
*/ | ||
void run(std::vector<uint32_t> originating_cluster, std::vector<uint32_t> all_destination_cluster, | ||
std::vector<uint32_t> healthy_destination_cluster) { | ||
setupRuntime(); | ||
stats_.upstream_zone_count_.set(all_destination_cluster.size()); | ||
|
||
std::unordered_map<std::string, std::vector<HostPtr>> healthy_map = | ||
generateMap(healthy_destination_cluster); | ||
std::unordered_map<std::string, std::vector<HostPtr>> all_map = | ||
generateMap(all_destination_cluster); | ||
|
||
std::vector<HostPtr> originatingHosts = generateList(originating_cluster); | ||
cluster_.healthy_hosts_ = generateList(healthy_destination_cluster); | ||
cluster_.hosts_ = generateList(all_destination_cluster); | ||
|
||
std::map<std::string, uint32_t> hits; | ||
for (uint32_t i = 0; i < total_number_of_requests; ++i) { | ||
HostPtr from_host = selectOriginatingHost(originatingHosts); | ||
|
||
cluster_.local_zone_hosts_ = all_map[from_host->zone()]; | ||
cluster_.local_zone_healthy_hosts_ = healthy_map[from_host->zone()]; | ||
|
||
ConstHostPtr selected = lb_.chooseHost(); | ||
hits[selected->url()]++; | ||
} | ||
|
||
for (const auto& host_hit_num_pair : hits) { | ||
std::cout << fmt::format("url:{}, hits:{}", host_hit_num_pair.first, host_hit_num_pair.second) | ||
<< std::endl; | ||
} | ||
} | ||
|
||
HostPtr selectOriginatingHost(const std::vector<HostPtr>& hosts) { | ||
// Originating cluster should have roughly the same per host request distribution. | ||
return hosts[random_.random() % hosts.size()]; | ||
} | ||
|
||
std::vector<HostPtr> generateList(const std::vector<uint32_t>& hosts) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better name and function comment, what does this do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed. |
||
std::vector<HostPtr> ret; | ||
for (size_t i = 0; i < hosts.size(); ++i) { | ||
const std::string zone = std::to_string(i); | ||
for (uint32_t j = 0; j < hosts[i]; ++j) { | ||
const std::string url = fmt::format("tcp://host.{}.{}:80", i, j); | ||
ret.push_back(newTestHost(cluster_, url, 1, zone)); | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
std::unordered_map<std::string, std::vector<HostPtr>> | ||
generateMap(const std::vector<uint32_t>& hosts) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better name and function comment, what does this do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
std::unordered_map<std::string, std::vector<HostPtr>> ret; | ||
for (size_t i = 0; i < hosts.size(); ++i) { | ||
const std::string zone = std::to_string(i); | ||
std::vector<HostPtr> zone_hosts; | ||
|
||
for (uint32_t j = 0; j < hosts[i]; ++j) { | ||
const std::string url = fmt::format("tcp://host.{}.{}:80", i, j); | ||
zone_hosts.push_back(newTestHost(cluster_, url, 1, zone)); | ||
} | ||
|
||
ret.insert({zone, std::move(zone_hosts)}); | ||
} | ||
|
||
return ret; | ||
}; | ||
|
||
void setupRuntime() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do in constructor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I actually meant just run this code in the constructor, you don't need the setupRuntime() function at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, ok, moving there |
||
ON_CALL(runtime_.snapshot_, getInteger("upstream.healthy_panic_threshold", 50U)) | ||
.WillByDefault(Return(50U)); | ||
ON_CALL(runtime_.snapshot_, featureEnabled("upstream.zone_routing.enabled", 100)) | ||
.WillByDefault(Return(true)); | ||
ON_CALL(runtime_.snapshot_, getInteger("upstream.zone_routing.percent_diff", 3)) | ||
.WillByDefault(Return(3)); | ||
} | ||
|
||
const uint32_t total_number_of_requests = 100000; | ||
|
||
NiceMock<MockCluster> cluster_; | ||
NiceMock<Runtime::MockLoader> runtime_; | ||
Runtime::RandomGeneratorImpl random_; | ||
Stats::IsolatedStoreImpl stats_store_; | ||
ClusterStats stats_; | ||
// TODO: make per originating host load balancer. | ||
RandomLoadBalancer lb_{cluster_, stats_, runtime_, random_}; | ||
}; | ||
|
||
TEST_F(DISABLED_SimulationTest, strictlyEqualDistribution) { | ||
run({1U, 1U, 1U}, {3U, 3U, 3U}, {3U, 3U, 3U}); | ||
} | ||
|
||
TEST_F(DISABLED_SimulationTest, unequalZoneDistribution) { | ||
run({1U, 1U, 1U}, {5U, 5U, 6U}, {5U, 5U, 6U}); | ||
} | ||
|
||
} // Upstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
originatingHosts naming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed