ClickHouse/dbms/src/Access/QuotaContext.h

114 lines
3.8 KiB
C++
Raw Normal View History

2019-11-04 19:17:27 +00:00
#pragma once
#include <Access/Quota.h>
#include <Core/UUID.h>
#include <Poco/Net/IPAddress.h>
#include <ext/shared_ptr_helper.h>
#include <boost/noncopyable.hpp>
#include <boost/smart_ptr/atomic_shared_ptr.hpp>
2019-11-04 19:17:27 +00:00
#include <atomic>
#include <chrono>
#include <memory>
namespace DB
{
struct QuotaUsageInfo;
/// Instances of `QuotaContext` are used to track resource consumption.
class QuotaContext : public boost::noncopyable
{
public:
using ResourceType = Quota::ResourceType;
using ResourceAmount = Quota::ResourceAmount;
/// Default constructors makes an unlimited quota.
QuotaContext();
~QuotaContext();
/// Tracks resource consumption. If the quota exceeded and `check_exceeded == true`, throws an exception.
void used(ResourceType resource_type, ResourceAmount amount, bool check_exceeded = true) const;
void used(const std::pair<ResourceType, ResourceAmount> & resource, bool check_exceeded = true) const;
void used(const std::pair<ResourceType, ResourceAmount> & resource1, const std::pair<ResourceType, ResourceAmount> & resource2, bool check_exceeded = true) const;
void used(const std::pair<ResourceType, ResourceAmount> & resource1, const std::pair<ResourceType, ResourceAmount> & resource2, const std::pair<ResourceType, ResourceAmount> & resource3, bool check_exceeded = true) const;
void used(const std::vector<std::pair<ResourceType, ResourceAmount>> & resources, bool check_exceeded = true) const;
2019-11-04 19:17:27 +00:00
/// Checks if the quota exceeded. If so, throws an exception.
void checkExceeded() const;
void checkExceeded(ResourceType resource_type) const;
2019-11-04 19:17:27 +00:00
/// Returns the information about this quota context.
QuotaUsageInfo getUsageInfo() const;
private:
friend class QuotaContextFactory;
friend struct ext::shared_ptr_helper<QuotaContext>;
/// Instances of this class are created by QuotaContextFactory.
2020-02-21 00:17:07 +00:00
QuotaContext(const String & user_name_, const UUID & user_id_, const std::vector<UUID> & enabled_roles_, const Poco::Net::IPAddress & address_, const String & client_key_);
2019-11-04 19:17:27 +00:00
static constexpr size_t MAX_RESOURCE_TYPE = Quota::MAX_RESOURCE_TYPE;
struct Interval
{
mutable std::atomic<ResourceAmount> used[MAX_RESOURCE_TYPE];
ResourceAmount max[MAX_RESOURCE_TYPE];
std::chrono::seconds duration;
bool randomize_interval;
mutable std::atomic<std::chrono::system_clock::duration> end_of_interval;
Interval() {}
Interval(const Interval & src) { *this = src; }
Interval & operator =(const Interval & src);
};
struct Intervals
{
std::vector<Interval> intervals;
UUID quota_id;
String quota_name;
String quota_key;
QuotaUsageInfo getUsageInfo(std::chrono::system_clock::time_point current_time) const;
};
struct Impl;
const String user_name;
2020-02-21 00:17:07 +00:00
const UUID user_id;
const std::vector<UUID> enabled_roles;
2019-11-04 19:17:27 +00:00
const Poco::Net::IPAddress address;
const String client_key;
boost::atomic_shared_ptr<const Intervals> intervals; /// atomically changed by QuotaUsageManager
2019-11-04 19:17:27 +00:00
};
using QuotaContextPtr = std::shared_ptr<const QuotaContext>;
2019-11-04 19:17:27 +00:00
/// The information about a quota context.
struct QuotaUsageInfo
{
using ResourceType = Quota::ResourceType;
using ResourceAmount = Quota::ResourceAmount;
static constexpr size_t MAX_RESOURCE_TYPE = Quota::MAX_RESOURCE_TYPE;
struct Interval
{
ResourceAmount used[MAX_RESOURCE_TYPE];
ResourceAmount max[MAX_RESOURCE_TYPE];
std::chrono::seconds duration = std::chrono::seconds::zero();
bool randomize_interval = false;
std::chrono::system_clock::time_point end_of_interval;
Interval();
};
std::vector<Interval> intervals;
UUID quota_id;
String quota_name;
String quota_key;
QuotaUsageInfo();
};
}