aegis.cpp
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
ratelimit.hpp
1 //
2 // ratelimit.hpp
3 // *************
4 //
5 // Copyright (c) 2019 Sharon W (sharon at aegis dot gg)
6 //
7 // Distributed under the MIT License. (See accompanying file LICENSE)
8 //
9 
10 #pragma once
11 
12 #include "aegis/config.hpp"
13 #include "aegis/rest/rest_controller.hpp"
14 #include "aegis/snowflake.hpp"
15 #include "aegis/ratelimit/bucket.hpp"
16 #include "aegis/futures.hpp"
17 #include "aegis/core.hpp"
18 
19 #include <chrono>
20 #include <functional>
21 #include <string>
22 #include <queue>
23 #include <map>
24 #include <atomic>
25 #include <mutex>
26 #include <type_traits>
27 namespace aegis
28 {
29 
30 namespace ratelimit
31 {
32 
33 using namespace std::chrono;
34 
36 
42 {
43 public:
45 
48  explicit ratelimit_mgr(rest_call call, asio::io_context & _io, core * _b)
49  : global_limit(0)
50  , _call(call)
51  , _io_context(_io)
52  , _bot(_b)
53  {
54 
55  }
56 
57  ratelimit_mgr(const ratelimit_mgr &) = delete;
58  ratelimit_mgr(ratelimit_mgr &&) = delete;
59  ratelimit_mgr & operator=(const ratelimit_mgr &) = delete;
60 
62 
65  bool is_global() const noexcept
66  {
67  return global_limit > 0;
68  }
69 
71 
76  bucket & get_bucket(const std::string & path) noexcept
77  {
78  // look for existing bucket
79  auto bkt = _buckets.find(path);
80  if (bkt != _buckets.end())
81  return *bkt->second;// found
82 
83  // create new bucket and return
84  return *_buckets.emplace(path, std::make_unique<bucket>(_call, _io_context, global_limit)).first->second;
85  }
86 
87  template<typename ResultType, typename V = std::enable_if_t<!std::is_same<ResultType, rest::rest_reply>::value>>
88  aegis::future<ResultType> post_task(rest::request_params params) noexcept
89  {
90  return _bot->async([=]() -> ResultType
91  {
92  auto & bkt = get_bucket(params.path);
93  auto res = bkt.perform(params);
94  if (res.reply_code < rest::ok || res.reply_code >= rest::multiple_choices)//error
95  throw aegis::exception(fmt::format("REST Reply Code: {}", static_cast<int>(res.reply_code)), bad_request);
96  return res.content.empty() ? ResultType(_bot) : ResultType(res.content, _bot);
97  });
98  }
99 
100  aegis::future<rest::rest_reply> post_task(rest::request_params params) noexcept
101  {
102  return _bot->async([=]() -> rest::rest_reply
103  {
104  auto & bkt = get_bucket(params.path);
105  return bkt.perform(params);
106  });
107  }
108 
109  template<typename ResultType, typename V = std::enable_if_t<!std::is_same<ResultType, rest::rest_reply>::value>>
110  aegis::future<ResultType> post_task(std::string _bucket, rest::request_params params) noexcept
111  {
112  return _bot->async([=]() -> ResultType
113  {
114  auto & bkt = get_bucket(_bucket);
115  auto res = bkt.perform(params);
116  if (res.reply_code < rest::ok || res.reply_code >= rest::multiple_choices)//error
117  throw aegis::exception(fmt::format("REST Reply Code: {}", static_cast<int>(res.reply_code)), bad_request);
118  return res.content.empty() ? ResultType(_bot) : ResultType(res.content, _bot);
119  });
120  }
121 
122  aegis::future<rest::rest_reply> post_task(std::string _bucket, rest::request_params params) noexcept
123  {
124  return _bot->async([=]() -> rest::rest_reply
125  {
126  auto & bkt = get_bucket(_bucket);
127  return bkt.perform(params);
128  });
129  }
130 
131 private:
132  friend class bucket;
133 
134  std::atomic<int64_t> global_limit;
136  std::unordered_map<std::string, std::unique_ptr<bucket>> _buckets;
137  rest_call _call;
138  asio::io_context & _io_context;
139  core * _bot;
140 };
141 
142 }
143 
144 }
bool is_global() const noexcept
Check if globally ratelimited.
Definition: ratelimit.hpp:65
bucket & get_bucket(const std::string &path) noexcept
Get a bucket object.
Definition: ratelimit.hpp:76
Definition: rest_controller.hpp:43
Primary class for managing a bot interface.
Definition: core.hpp:157
Definition: error.hpp:176
future
Definition: futures.hpp:41
ratelimit_mgr(rest_call call, asio::io_context &_io, core *_b)
Construct a ratelimit_mgr object for managing the bucket factories.
Definition: ratelimit.hpp:48
Factory class for managing ratelimit bucket factory objects.
Definition: ratelimit.hpp:41
Buckets store ratelimit data per major parameter.
Definition: bucket.hpp:49