diff --git a/cachelib/allocator/CacheAllocator.h b/cachelib/allocator/CacheAllocator.h index b485a5fba..4e98b3e61 100644 --- a/cachelib/allocator/CacheAllocator.h +++ b/cachelib/allocator/CacheAllocator.h @@ -6359,6 +6359,7 @@ folly::IOBufQueue CacheAllocator::saveStateToIOBuf() { template bool CacheAllocator::stopWorkers(std::chrono::seconds timeout) { bool success = true; + success &= stopPoolOptimizer(timeout); success &= stopPoolRebalancer(timeout); success &= stopPoolResizer(timeout); success &= stopMemMonitor(timeout); diff --git a/cachelib/allocator/tests/SimplePoolOptimizationTest.cpp b/cachelib/allocator/tests/SimplePoolOptimizationTest.cpp index 63b567f0e..e01c3d59c 100644 --- a/cachelib/allocator/tests/SimplePoolOptimizationTest.cpp +++ b/cachelib/allocator/tests/SimplePoolOptimizationTest.cpp @@ -29,6 +29,10 @@ TYPED_TEST(SimplePoolOptimizationTest, PoolOptimizerBasic) { this->testPoolOptimizerBasic(); } +TYPED_TEST(SimplePoolOptimizationTest, StopWorkersStopsPoolOptimizer) { + this->testStopWorkersStopsPoolOptimizer(); +} + } // namespace tests } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/tests/SimplePoolOptimizationTest.h b/cachelib/allocator/tests/SimplePoolOptimizationTest.h index 2313ef4f6..13c77dd85 100644 --- a/cachelib/allocator/tests/SimplePoolOptimizationTest.h +++ b/cachelib/allocator/tests/SimplePoolOptimizationTest.h @@ -19,7 +19,10 @@ #include #include +#include +#include #include +#include #include "cachelib/allocator/CCacheAllocator.h" #include "cachelib/allocator/PoolOptimizer.h" @@ -85,6 +88,34 @@ struct SimplePoolOptimizeStrategy : public PoolOptimizeStrategy { template class SimplePoolOptimizationTest : public testing::Test { public: + void testStopWorkersStopsPoolOptimizer() { + struct CountingStrategy : public PoolOptimizeStrategy { + std::atomic calls{0}; + + protected: + PoolOptimizeContext pickVictimAndReceiverRegularPoolsImpl( + const CacheBase&) override { + ++calls; + return kNoOpContext; + } + }; + auto strategy = std::make_shared(); + typename AllocatorT::Config config; + config.setCacheSize(30 * Slab::kSize); + config.enablePoolOptimizer(strategy, std::chrono::seconds{1}, + std::chrono::seconds{1}, 1); + AllocatorT alloc(config); + for (int i = 0; i < 100 && strategy->calls == 0; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + } + ASSERT_GT(strategy->calls.load(), 0); + + ASSERT_TRUE(alloc.stopWorkers()); + const int calls = strategy->calls.load(); + std::this_thread::sleep_for(std::chrono::seconds{2}); + EXPECT_EQ(calls, strategy->calls.load()); + } + void testPoolOptimizerBasic() { typename AllocatorT::Config config; config.setCacheSize(30 * Slab::kSize);