diff --git a/searchcore/src/tests/proton/persistenceengine/resource_usage_tracker/resource_usage_tracker_test.cpp b/searchcore/src/tests/proton/persistenceengine/resource_usage_tracker/resource_usage_tracker_test.cpp index 313f3e9a270d..c0d94ba6376f 100644 --- a/searchcore/src/tests/proton/persistenceengine/resource_usage_tracker/resource_usage_tracker_test.cpp +++ b/searchcore/src/tests/proton/persistenceengine/resource_usage_tracker/resource_usage_tracker_test.cpp @@ -57,9 +57,10 @@ class ResourceUsageTrackerTest : public ::testing::Test ~ResourceUsageTrackerTest(); - void notify(double disk_usage, double memory_usage) + void notify(double disk_usage, double memory_usage, double transient_disk_usage = 0.0, double transient_memory_usage = 0.0) { - _notifier.notify(DiskMemUsageState({ 0.8, disk_usage }, { 0.8, memory_usage })); + _notifier.notify(DiskMemUsageState({ 0.8, disk_usage }, { 0.8, memory_usage }, + transient_disk_usage, transient_memory_usage)); } ResourceUsage get_usage() { return _listener->get_usage(); } @@ -77,6 +78,15 @@ TEST_F(ResourceUsageTrackerTest, resource_usage_is_forwarded_to_listener) EXPECT_EQ(ResourceUsage(0.75, 0.25), get_usage()); } +TEST_F(ResourceUsageTrackerTest, transient_resource_usage_is_subtracted_from_absolute_usage) +{ + auto register_guard = _tracker->set_listener(*_listener); + notify(0.8, 0.5, 0.4, 0.2); + EXPECT_EQ(ResourceUsage(0.4, 0.3), get_usage()); + notify(0.8, 0.5, 0.9, 0.6); + EXPECT_EQ(ResourceUsage(0.0, 0.0), get_usage()); +} + TEST_F(ResourceUsageTrackerTest, forwarding_depends_on_register_guard) { auto register_guard = _tracker->set_listener(*_listener); diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/resource_usage_tracker.cpp b/searchcore/src/vespa/searchcore/proton/persistenceengine/resource_usage_tracker.cpp index 6307604598d0..63e8b1d51962 100644 --- a/searchcore/src/vespa/searchcore/proton/persistenceengine/resource_usage_tracker.cpp +++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/resource_usage_tracker.cpp @@ -94,8 +94,13 @@ void ResourceUsageTracker::notifyDiskMemUsage(DiskMemUsageState state) { std::lock_guard guard(_lock); - // TODO: Subtract transient resource (memory and disk) usage from the absolute numbers. - _resource_usage = ResourceUsage(state.diskState().usage(), state.memoryState().usage(), _resource_usage.get_attribute_address_space_usage()); + // The transient resource usage is subtracted from the absolute resource usage + // before it eventually is reported to the cluster controller (to decide whether to block client feed). + // This ensures that the transient resource usage is covered by the resource headroom on the content node, + // instead of leading to feed blocked due to natural fluctuations. + double adj_disk_usage = std::max(0.0, state.diskState().usage() - state.transient_disk_usage()); + double adj_memory_usage = std::max(0.0, state.memoryState().usage() - state.transient_memory_usage()); + _resource_usage = ResourceUsage(adj_disk_usage, adj_memory_usage, _resource_usage.get_attribute_address_space_usage()); if (_listener != nullptr) { _listener->update_resource_usage(_resource_usage); }