| 37 | PoolResizer::~PoolResizer() { stop(std::chrono::seconds(0)); } |
| 38 | |
| 39 | void PoolResizer::work() { |
| 40 | const auto pools = cache_.getRegularPoolIdsForResize(); |
| 41 | for (auto poolId : pools) { |
| 42 | const PoolStats poolStats = cache_.getPoolStats(poolId); |
| 43 | unsigned int numIterations = 0; |
| 44 | while (numIterations < numSlabsPerIteration_) { |
| 45 | // check if the pool still needs resizing after each iteration. |
| 46 | if (!cache_.getPool(poolId).overLimit()) { |
| 47 | numIterations++; |
| 48 | continue; |
| 49 | } |
| 50 | // if user had supplied a rebalance stategy for the pool, |
| 51 | // use that to downsize it |
| 52 | auto strategy = cache_.getResizeStrategy(poolId); |
| 53 | if (!strategy) { |
| 54 | strategy = strategy_; |
| 55 | } |
| 56 | |
| 57 | // use the rebalance strategy and see if there is some allocation class |
| 58 | // that is over provisioned. |
| 59 | const auto classId = strategy->pickVictimForResizing(cache_, poolId); |
| 60 | |
| 61 | try { |
| 62 | const auto now = util::getCurrentTimeMs(); |
| 63 | // Throws excption if the strategy did not pick a valid victim classId. |
| 64 | cache_.releaseSlab(poolId, classId, SlabReleaseMode::kResize); |
| 65 | XLOGF(DBG, "Moved a slab from classId {} for poolid: {}", |
| 66 | static_cast<int>(classId), static_cast<int>(poolId)); |
| 67 | ++slabsReleased_; |
| 68 | const auto elapsed_time = |
| 69 | static_cast<uint64_t>(util::getCurrentTimeMs() - now); |
| 70 | // Log the event about the Pool which released the Slab along with |
| 71 | // the number of slabs. Only Victim Pool class information is |
| 72 | // relevant here. |
| 73 | stats_.addSlabReleaseEvent( |
| 74 | classId, Slab::kInvalidClassId, /* No receiver Class info */ |
| 75 | elapsed_time, poolId, 1, 1, /* One Slab moved */ |
| 76 | poolStats.allocSizeForClass(classId), 0, |
| 77 | poolStats.evictionAgeForClass(classId), 0, |
| 78 | poolStats.mpStats.acStats.at(classId).freeAllocs); |
| 79 | numIterations++; |
| 80 | } catch (const exception::SlabReleaseAborted& e) { |
| 81 | cache_.incrementAbortedSlabReleases(); |
| 82 | if (cache_.isShutdownInProgress()) { |
| 83 | XLOGF(WARN, |
| 84 | "Shutdown in progress, aborted trying to resize pool {} for " |
| 85 | "allocation class {}. " |
| 86 | "Error: {}", |
| 87 | static_cast<int>(poolId), static_cast<int>(classId), e.what()); |
| 88 | return; |
| 89 | } |
| 90 | // It's a timeout, log and continue with next slab |
| 91 | XLOGF(WARN, |
| 92 | "PoolResizer: Timeout while releasing slab for pool {} for " |
| 93 | "allocation class {}. Error: {}", |
| 94 | static_cast<int>(poolId), static_cast<int>(classId), e.what()); |
| 95 | } catch (const std::exception& e) { |
| 96 | XLOGF( |
nothing calls this directly
no test coverage detected