OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
parsec/ticket_machine/client.cpp
Go to the documentation of this file.
1// Copyright (c) 2021 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "client.hpp"
7
9
11 client::client(std::vector<network::endpoint_t> endpoints)
12 : m_client(std::make_unique<decltype(m_client)::element_type>(
13 std::move(endpoints))) {}
14
15 auto client::init() -> bool {
16 return m_client->init();
17 }
18
19 auto
21 -> bool {
22 auto num = ticket_number_type{};
23 {
24 std::unique_lock l(m_mut);
25 constexpr auto fetch_threshold = 500;
26 if(m_tickets.size() < fetch_threshold && !m_fetching_tickets) {
27 auto res = fetch_tickets();
28 if(res) {
29 m_fetching_tickets = true;
30 }
31 if(m_tickets.empty() && !res) {
32 return false;
33 }
34 }
35 if(m_tickets.empty()) {
36 m_callbacks.emplace(std::move(result_callback));
37 return true;
38 }
39
40 num = m_tickets.front();
41 m_tickets.pop();
42 }
43
44 result_callback(ticket_number_range_type{num, num});
45 return true;
46 }
47
48 auto client::fetch_tickets() -> bool {
49 return m_client->call(
50 std::monostate{},
51 [this](std::optional<get_ticket_number_return_type> res) {
52 assert(res.has_value());
53 std::visit(overloaded{[&](ticket_number_range_type range) {
54 handle_ticket_numbers(range);
55 },
56 [&](error_code e) {
57 auto callbacks
58 = decltype(m_callbacks)();
59 {
60 std::unique_lock ll(m_mut);
61 m_fetching_tickets = false;
62 callbacks.swap(m_callbacks);
63 }
64 while(!callbacks.empty()) {
65 callbacks.front()(e);
66 callbacks.pop();
67 }
68 }},
69 res.value());
70 });
71 }
72
73 void client::handle_ticket_numbers(ticket_number_range_type range) {
74 auto callbacks = decltype(m_callbacks)();
75 auto tickets = decltype(m_tickets)();
76 {
77 std::unique_lock ll(m_mut);
78 for(ticket_number_type i = range.first; i < range.second; i++) {
79 m_tickets.push(i);
80 }
81 while(!m_tickets.empty() && !m_callbacks.empty()) {
82 callbacks.push(std::move(m_callbacks.front()));
83 m_callbacks.pop();
84 tickets.push(m_tickets.front());
85 m_tickets.pop();
86 }
87 if(m_callbacks.empty()) {
88 m_fetching_tickets = false;
89 } else {
90 auto fetch_res = fetch_tickets();
91 if(!fetch_res) {
92 m_fetching_tickets = false;
93 }
94 }
95 }
96 while(!callbacks.empty()) {
97 assert(!tickets.empty());
98 callbacks.front()(
99 ticket_number_range_type{tickets.front(), tickets.front()});
100 callbacks.pop();
101 tickets.pop();
102 }
103 }
104}
std::function< void(get_ticket_number_return_type)> get_ticket_number_callback_type
Callback function type for asynchronously handling ticket number requests.
std::pair< ticket_number_type, ticket_number_type > ticket_number_range_type
Return value from the ticket machine in the success case.
auto init() -> bool
Initializes the underlying TCP client.
auto get_ticket_number(get_ticket_number_callback_type result_callback) -> bool override
Requests a new batch of ticket numbers from the remote ticket machine.
uint64_t ticket_number_type
Type alias for a ticket number.
Variant handler template.