2022-09-27 13:26:41 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <IO/ISchedulerNode.h>
|
2023-01-27 18:47:22 +00:00
|
|
|
#include <IO/ResourceBudget.h>
|
|
|
|
#include <IO/ResourceRequest.h>
|
2022-09-27 13:26:41 +00:00
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Queue for pending requests for specific resource, leaf of hierarchy.
|
2023-01-27 18:47:22 +00:00
|
|
|
* Note that every queue has budget associated with it.
|
2022-09-27 13:26:41 +00:00
|
|
|
*/
|
|
|
|
class ISchedulerQueue : public ISchedulerNode
|
|
|
|
{
|
|
|
|
public:
|
2023-01-27 18:47:22 +00:00
|
|
|
explicit ISchedulerQueue(EventQueue * event_queue_, const Poco::Util::AbstractConfiguration & config = emptyConfig(), const String & config_prefix = {})
|
2022-09-27 13:26:41 +00:00
|
|
|
: ISchedulerNode(event_queue_, config, config_prefix)
|
|
|
|
{}
|
|
|
|
|
2023-01-27 18:47:22 +00:00
|
|
|
// Wrapper for `enqueueRequest()` that should be used to account for available resource budget
|
|
|
|
void enqueueRequestUsingBudget(ResourceRequest * request)
|
|
|
|
{
|
|
|
|
request->cost = budget.ask(request->cost);
|
|
|
|
enqueueRequest(request);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be called to account for difference between real and estimated costs
|
|
|
|
void adjustBudget(ResourceCost estimated_cost, ResourceCost real_cost)
|
|
|
|
{
|
|
|
|
budget.adjust(estimated_cost, real_cost);
|
|
|
|
}
|
|
|
|
|
2023-01-27 22:48:02 +00:00
|
|
|
// Adjust budget to account for extra consumption of `cost` resource units
|
2023-01-27 18:47:22 +00:00
|
|
|
void consumeBudget(ResourceCost cost)
|
|
|
|
{
|
|
|
|
adjustBudget(0, cost);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adjust budget to account for requested, but not consumed `cost` resource units
|
|
|
|
void accumulateBudget(ResourceCost cost)
|
|
|
|
{
|
|
|
|
adjustBudget(cost, 0);
|
|
|
|
}
|
|
|
|
|
2022-09-27 13:26:41 +00:00
|
|
|
/// Enqueue new request to be executed using underlying resource.
|
|
|
|
/// Should be called outside of scheduling subsystem, implementation must be thread-safe.
|
|
|
|
virtual void enqueueRequest(ResourceRequest * request) = 0;
|
2023-01-27 18:47:22 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Allows multiple consumers to synchronize with common "debit/credit" balance.
|
|
|
|
// 1) (positive) to avoid wasting of allocated but not used resource (e.g in case of a failure);
|
2023-01-27 22:48:02 +00:00
|
|
|
// 2) (negative) to account for overconsumption (e.g. if cost is not know in advance and estimation from below is applied).
|
2023-01-27 18:47:22 +00:00
|
|
|
ResourceBudget budget;
|
2022-09-27 13:26:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|