OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
rate_limiting_protocol.hpp
1#pragma once
3#include <ossia/detail/thread.hpp>
4#include <ossia/detail/flat_map.hpp>
5#include <ossia/network/base/message_queue.hpp>
6#include <ossia/network/base/parameter_data.hpp>
7#include <ossia/network/base/protocol.hpp>
8
9#include <readerwriterqueue.h>
10
11#include <chrono>
12#include <thread>
13#include <vector>
14
15namespace ossia::net
16{
17struct rate_limiter;
18class OSSIA_EXPORT rate_limiting_protocol final : public ossia::net::protocol_base
19{
20public:
21 using clock = std::chrono::high_resolution_clock;
22 using duration = clock::duration;
23 rate_limiting_protocol(duration d, std::unique_ptr<protocol_base> arg);
24 ~rate_limiting_protocol() override;
25
26 void set_duration(duration d);
27
28private:
29 bool pull(ossia::net::parameter_base&) override;
30 bool push(const ossia::net::parameter_base& addr, const ossia::value& v) override;
31 bool push_raw(const full_parameter_data&) override;
32 bool observe(ossia::net::parameter_base&, bool) override;
33 bool update(ossia::net::node_base& node_base) override;
34
35 void set_logger(const network_logger& l) override;
36 const network_logger& get_logger() const noexcept override;
37
38 void stop() override;
39 void set_device(ossia::net::device_base& dev) override;
40
41 void parameter_removed(const ossia::net::parameter_base& b);
42
43 rate_limiting_protocol() = delete;
44 rate_limiting_protocol(const rate_limiting_protocol&) = delete;
45 rate_limiting_protocol(rate_limiting_protocol&&) = delete;
46 rate_limiting_protocol& operator=(const rate_limiting_protocol&) = delete;
47 rate_limiting_protocol& operator=(rate_limiting_protocol&&) = delete;
48
49 friend struct rate_limiter;
50
51 std::atomic<duration> m_duration{};
52 std::unique_ptr<ossia::net::protocol_base> m_protocol;
53 ossia::net::device_base* m_device{};
54
55 std::atomic_bool m_running{true};
56 ossia::thread m_thread;
57
58 clock::time_point m_lastTime;
59 using map_t = ossia::flat_map<
60 const ossia::net::parameter_base*, std::pair<ossia::value, clock::time_point>>;
61 map_t m_userMessages;
62 map_t m_buffer;
63 map_t m_threadMessages;
64 std::mutex m_msgMutex;
65};
66
67template <typename Protocol, typename... Args>
68auto limit_output_rate(std::chrono::milliseconds ms, Args&&... args)
69{
70 return std::make_unique<rate_limiting_protocol>(
71 ms, std::make_unique<Protocol>(std::forward<Args>(args)...));
72}
73
74}