aegis.cpp
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
shard_mgr.hpp
1 //
2 // shard_mgr.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/utility.hpp"
14 #include "aegis/snowflake.hpp"
15 #include "aegis/error.hpp"
16 #include "aegis/shards/shard.hpp"
17 #include <websocketpp/config/asio_client.hpp>
18 #include <websocketpp/common/connection_hdl.hpp>
19 #include <websocketpp/client.hpp>
20 #include "spdlog/spdlog.h"
21 
22 #include <vector>
23 #include <iostream>
24 #include <string>
25 
26 #include <asio/bind_executor.hpp>
27 
28 namespace aegis
29 {
30 
31 namespace shards
32 {
33 
34 using json = nlohmann::json;
35 using namespace std::literals;
36 
38 
41 class shard_mgr
42 {
43 public:
45  using websocket = websocketpp::client<websocketpp::config::asio_tls_client>;
46 
48  using connection_ptr = websocketpp::client<websocketpp::config::asio_tls_client>::connection_type::ptr;
49 
51  using message_ptr = websocketpp::config::asio_client::message_type::ptr;
52 
54 
63  AEGIS_DECL shard_mgr(std::string token, asio::io_context & _io, std::shared_ptr<spdlog::logger> log);
64 
66  AEGIS_DECL ~shard_mgr();
67 
68  shard_mgr(const shard_mgr &) = delete;
69  shard_mgr(shard_mgr &&) = delete;
70  shard_mgr & operator=(const shard_mgr &) = delete;
71 
73 
76  AEGIS_DECL void setup_callbacks(shard * _shard) noexcept;
77 
79 
83  AEGIS_DECL void debug_trace(shard * _shard, bool extended = false) noexcept;
84 
86 
89  asio::io_context & get_io_context()
90  {
91  return _io_context;
92  }
93 
96  AEGIS_DECL void shutdown();
97 
99 
102  websocket & get_websocket() noexcept { return websocket_o; }
103 
105 
109  bot_status get_state() const noexcept { return _status; }
110 
112 
116  void set_state(bot_status s) noexcept { _status = s; }
117 
119 
122  AEGIS_DECL std::string uptime() const noexcept;
123 
125 
128  AEGIS_DECL void send_all_shards(const std::string & msg);
129 
131 
134  AEGIS_DECL void send_all_shards(const json & msg);
135 
137  AEGIS_DECL void start();
138 
140  using t_on_message = std::function<void(websocketpp::connection_hdl hdl, std::string msg, shard * _shard)>;
142  using t_on_connect = std::function<void(websocketpp::connection_hdl hdl, shard * _shard)>;
144  using t_on_close = std::function<void(websocketpp::connection_hdl hdl, shard * _shard)>;
145 
147 
151  void set_on_message(t_on_message cb) noexcept
152  {
153  i_on_message = cb;
154  }
155 
157 
161  void set_on_connect(t_on_connect cb) noexcept
162  {
163  i_on_connect = cb;
164  }
165 
167 
171  void set_on_close(t_on_close cb) noexcept
172  {
173  i_on_close = cb;
174  }
175 
177 
180  void set_gateway_url(const std::string & url) noexcept
181  {
182  gateway_url = url;
183  }
184 
186 
189  std::string get_gateway_url() const noexcept
190  {
191  return gateway_url;
192  }
193 
195 
198  AEGIS_DECL void reset_shard(shard * _shard, shard_status _status = shard_status::closing) noexcept;
199 
201 
204  AEGIS_DECL void queue_reconnect(shard * _shard) noexcept;
205 
207 
210  void queue_reconnect(shard & _shard)
211  {
212  queue_reconnect(&_shard);
213  }
214 
216 
219  AEGIS_DECL void connect(shard * _shard) noexcept;
220 
222 
227  AEGIS_DECL shard & get_shard(uint16_t shard_id);
228 
230 
233  AEGIS_DECL const std::vector<std::unique_ptr<shard>> & get_shards() const noexcept
234  {
235  return _shards;
236  }
237 
239 
246  AEGIS_DECL void close(shard * _shard, int32_t code = 1001, const std::string & reason = "", shard_status connection_state = shard_status::closing) noexcept;
247 
249 
256  void close(shard & _shard, int32_t code = 1001, const std::string & reason = "", shard_status connection_state = shard_status::closing) noexcept
257  {
258  close(&_shard, code, reason, connection_state);
259  }
260 
262 
265  uint32_t shard_count() const noexcept
266  {
267  return _shards.size();
268  }
269 
271  asio::io_context & _io_context;
272 
274  std::string ws_gateway;
275 
277  std::unordered_map<std::string, uint64_t> message_count;
278 
282  uint32_t shard_max_count;
284  std::shared_ptr<spdlog::logger> log;
285 
286 private:
287  friend aegis::core;
288 
289  std::chrono::time_point<std::chrono::steady_clock> _last_ready;
290  std::chrono::time_point<std::chrono::steady_clock> _last_identify;
291  std::chrono::time_point<std::chrono::steady_clock> _connect_time;
292  shard * _connecting_shard;
293 
294  std::vector<std::unique_ptr<shard>> _shards;
295 
296  t_on_message i_on_message;
297  t_on_connect i_on_connect;
298  t_on_close i_on_close;
299 
300  std::function<void(aegis::shards::shard*)> i_shard_disconnect;
301  std::function<void(aegis::shards::shard*)> i_shard_connect;
302 
303  AEGIS_DECL void _on_message(websocketpp::connection_hdl hdl, message_ptr msg, shard * _shard);
304  AEGIS_DECL void _on_connect(websocketpp::connection_hdl hdl, shard * _shard);
305  AEGIS_DECL void _on_close(websocketpp::connection_hdl hdl, shard * _shard);
306  AEGIS_DECL void ws_status(const asio::error_code & ec);
307 
308  std::chrono::steady_clock::time_point starttime;
309 
310  // Gateway URL for the Discord Websocket
311  std::string gateway_url;
312 
313  // Websocket++ object
314  websocket websocket_o;
315 
316  // Bot's token
317  std::string _token;
318 
319  bot_status _status;
320 
321  std::shared_ptr<asio::steady_timer> ws_timer;
322  std::shared_ptr<asio::steady_timer> ws_connect_timer;
323  std::deque<shard*> _shards_to_connect;
324 };
325 
326 }
327 
328 }
329 
330 #if defined(AEGIS_HEADER_ONLY)
331 #include "aegis/shards/impl/shard_mgr.cpp"
332 #endif
websocketpp::client< websocketpp::config::asio_tls_client > websocket
Type of a pointer to the Websocket++ client.
Definition: shard_mgr.hpp:45
void set_gateway_url(const std::string &url) noexcept
Set the gateway url the shards will connect to.
Definition: shard_mgr.hpp:180
void set_state(bot_status s) noexcept
Set the current shard manager state.
Definition: shard_mgr.hpp:116
std::unordered_map< std::string, uint64_t > message_count
Websocket event message counters.
Definition: shard_mgr.hpp:277
std::function< void(websocketpp::connection_hdl hdl, shard *_shard)> t_on_connect
Websocket on_connect handler type.
Definition: shard_mgr.hpp:142
void set_on_close(t_on_close cb) noexcept
Set handler for websocket disconnections.
Definition: shard_mgr.hpp:171
std::function< void(websocketpp::connection_hdl hdl, shard *_shard)> t_on_close
Websocket on_close handler type.
Definition: shard_mgr.hpp:144
Primary class for managing a bot interface.
Definition: core.hpp:157
uint32_t shard_count() const noexcept
Get the amount of shards that exist.
Definition: shard_mgr.hpp:265
bot_status get_state() const noexcept
Get the current state of the shard manager.
Definition: shard_mgr.hpp:109
void set_on_connect(t_on_connect cb) noexcept
Set handler for websocket connections.
Definition: shard_mgr.hpp:161
Primary class for managing a bot interface.
Definition: shard_mgr.hpp:41
uint32_t force_shard_count
Shard count to force manager to use.
Definition: shard_mgr.hpp:280
std::string ws_gateway
Gateway URL.
Definition: shard_mgr.hpp:274
std::shared_ptr< spdlog::logger > log
Logging instance.
Definition: shard_mgr.hpp:284
std::string get_gateway_url() const noexcept
Get the gateway url the shards will connect to.
Definition: shard_mgr.hpp:189
websocketpp::config::asio_client::message_type::ptr message_ptr
Type of a pointer to the Websocket++ message payload.
Definition: shard_mgr.hpp:51
uint32_t shard_max_count
Shard count retrieved from gateway.
Definition: shard_mgr.hpp:282
asio::io_context & _io_context
Asio context.
Definition: shard_mgr.hpp:271
websocket & get_websocket() noexcept
Get the internal Websocket++ instance.
Definition: shard_mgr.hpp:102
websocketpp::client< websocketpp::config::asio_tls_client >::connection_type::ptr connection_ptr
Type of a pointer to the Websocket++ TLS connection.
Definition: shard_mgr.hpp:48
const std::vector< std::unique_ptr< shard > > & get_shards() const noexcept
Get a const vector of all the shards.
Definition: shard_mgr.hpp:233
std::function< void(websocketpp::connection_hdl hdl, std::string msg, shard *_shard)> t_on_message
Websocket on_message handler type.
Definition: shard_mgr.hpp:140
Tracks websocket shards and their connections.
Definition: shard.hpp:42