diff --git a/mcrouter/routes/McRouteHandleProvider-inl.h b/mcrouter/routes/McRouteHandleProvider-inl.h index 7694df66a..a25ecfcf3 100644 --- a/mcrouter/routes/McRouteHandleProvider-inl.h +++ b/mcrouter/routes/McRouteHandleProvider-inl.h @@ -124,7 +124,6 @@ McRouteHandleProvider::createAsynclogRoute( if (!proxy_.router().opts().asynclog_disable) { target = makeAsynclogRoute(std::move(target), asynclogName); } - asyncLogRoutes_.emplace(std::move(asynclogName), target); return target; } @@ -552,8 +551,8 @@ McRouteHandleProvider::createSRRoute( if (auto* jNeedAsynclog = json.get_ptr("asynclog")) { needAsynclog = parseBool(*jNeedAsynclog, "asynclog"); } + folly::StringPiece asynclogName; if (needAsynclog) { - folly::StringPiece asynclogName; if (auto jAsynclogName = json.get_ptr("asynclog_name")) { asynclogName = parseString(*jAsynclogName, "asynclog_name"); } else if (auto jServiceName = json.get_ptr("service_name")) { @@ -573,6 +572,10 @@ McRouteHandleProvider::createSRRoute( } route = bucketize(std::move(route), json); + if (needAsynclog) { + asyncLogRoutes_.emplace(asynclogName.toString(), route); + } + if (auto jSRRouteName = json.get_ptr("service_name")) { auto srRouteName = parseString(*jSRRouteName, "service_name"); tierRoutes_.emplace(srRouteName, srRoute); @@ -711,6 +714,9 @@ McRouteHandleProvider::makePoolRoute( tierRoutes_.emplace(poolId, poolRoute); } } + if (needAsynclog) { + asyncLogRoutes_.emplace(asynclogName.toString(), route); + } return route; } catch (const std::exception& e) { throwLogic("PoolRoute {}: {}", poolJson.name, e.what()); diff --git a/mcrouter/test/cpp_unit_tests/mc_route_handle_provider_test.cpp b/mcrouter/test/cpp_unit_tests/mc_route_handle_provider_test.cpp index d06a5f17d..a7266f0ef 100644 --- a/mcrouter/test/cpp_unit_tests/mc_route_handle_provider_test.cpp +++ b/mcrouter/test/cpp_unit_tests/mc_route_handle_provider_test.cpp @@ -56,6 +56,33 @@ const char* const kPoolRoute = "hash": { "hash_func": "Crc32" } })"; +const char* const kBucketizedSRRoute = + R"({ + "type": "SRRoute", + "service_name": "twmemcache.shadow.bucketization-test", + "server_timeout": 200, + "asynclog_name": "test.asynclog", + "axonlog": false, + "bucketize": true, + "total_buckets": 1000, + "bucketize_until": 1000, + "bucketization_keyspace": "tst" +})"; + +const char* const kBucketizedPoolRoute = + R"({ + "type": "PoolRoute", + "pool": { "name": "mock", "servers": [ ] }, + "pool_id": "twmemcache.shadow.bucketization-test", + "hash": "WeightedCh3", + "asynclog_name": "test.asynclog", + "axonlog": false, + "bucketize": true, + "total_buckets": 1000, + "bucketize_until": 1000, + "bucketization_keyspace": "tst" +})"; + struct TestSetup { public: TestSetup() @@ -85,6 +112,7 @@ struct TestSetup { static McrouterOptions getOpts() { auto opts = defaultTestOptions(); + opts.enable_service_router = true; opts.config = std::string("file:") + kMemcacheConfig; return opts; } @@ -122,3 +150,31 @@ TEST(McRouteHandleProvider, pool_route) { EXPECT_EQ(1, asynclogRoutes.size()); EXPECT_EQ("asynclog:mock", asynclogRoutes["mock"]->routeName()); } + +TEST(McRouteHandleProvider, bucketized_sr_route_and_mcreplay_asynclogRoutes) { + TestSetup setup; + auto rh = setup.getRoute(kBucketizedSRRoute); + EXPECT_TRUE(rh != nullptr); + EXPECT_EQ( + "bucketize|total_buckets=1000|bucketize_until=1000|salt=|bucketization_keyspace=tst", + rh->routeName()); + auto asynclogRoutes = setup.provider().releaseAsyncLogRoutes(); + EXPECT_EQ(1, asynclogRoutes.size()); + EXPECT_EQ( + "bucketize|total_buckets=1000|bucketize_until=1000|salt=|bucketization_keyspace=tst", + asynclogRoutes["test.asynclog"]->routeName()); +} + +TEST(McRouteHandleProvider, bucketized_pool_route_and_mcreplay_asynclogRoutes) { + TestSetup setup; + auto rh = setup.getRoute(kBucketizedPoolRoute); + EXPECT_TRUE(rh != nullptr); + EXPECT_EQ( + "bucketize|total_buckets=1000|bucketize_until=1000|salt=|bucketization_keyspace=tst", + rh->routeName()); + auto asynclogRoutes = setup.provider().releaseAsyncLogRoutes(); + EXPECT_EQ(1, asynclogRoutes.size()); + EXPECT_EQ( + "bucketize|total_buckets=1000|bucketize_until=1000|salt=|bucketization_keyspace=tst", + asynclogRoutes["test.asynclog"]->routeName()); +}