Back to Site
Loading...
Searching...
No Matches
reconnection.h
Go to the documentation of this file.
1#pragma once
2
24#include "node/peer_network.h"
25#include "peer/peer.h"
26#include "core/address.h"
27#include "peer/peer_id.h"
28#include "peer/peer_book.h"
29
30#include <atomic>
31#include <chrono>
32#include <condition_variable>
33#include <memory>
34#include <mutex>
35#include <string>
36#include <thread>
37#include <unordered_map>
38
39namespace librats {
40
41class ReconnectionService final : public Subsystem {
42public:
43 struct Config {
44 std::string store_path = "";
45 bool persist_discovered = true;
46 size_t max_targets = 1024;
47 size_t max_attempts = 0;
48 size_t startup_targets = 32;
49 size_t archive_max = 4096;
50 std::chrono::seconds archive_max_age{std::chrono::hours(24 * 30)};
51 std::chrono::milliseconds base_backoff{1000};
52 std::chrono::milliseconds max_backoff{60000};
53 std::chrono::milliseconds tick{1000};
54 std::chrono::milliseconds dial_timeout{15000};
55 };
56
58 explicit ReconnectionService(Config config);
60
62 void add(const Address& address);
63
68 void remove(const Address& address);
69
70 size_t target_count() const;
71
76 std::vector<Address> known_peers(size_t n) const;
77
78 void attach(NodeContext& ctx) override;
79 void start() override;
80 void stop() override;
81
82private:
83 struct Target {
84 Address address;
85 bool dialing = false;
86 int attempts = 0;
87 std::chrono::steady_clock::time_point next_attempt;
88 std::chrono::steady_clock::time_point dial_deadline;
89 };
90
91 void on_connected(const Peer& peer);
92 void on_disconnected(const PeerId& id);
93 void on_dial_failed(const Address& address);
94 void loop();
95 std::chrono::milliseconds backoff_for(int attempts) const;
96
97 Config config_;
98 PeerNetwork* network_ = nullptr;
99 // Built once in the constructor (when store_path is set) and never reassigned,
100 // so the pointer is safe to read from any thread; PeerBook is itself internally
101 // synchronized. (Creating it in start() raced reads from on_connected, which can
102 // fire on a reactor thread before this subsystem's start() returns.)
103 std::unique_ptr<PeerBook> book_;
104
105 std::thread thread_;
106 std::atomic<bool> running_{false};
107 std::mutex wait_mutex_;
108 std::condition_variable wake_;
109
110 mutable std::mutex mutex_;
111 std::unordered_map<std::string, Target> targets_;
112};
113
114} // namespace librats
A dialable transport address (ip + port).
ReconnectionService(Config config)
std::vector< Address > known_peers(size_t n) const
The passive reserve pool: up to n best-known peer addresses from the book (history of everyone we hav...
void add(const Address &address)
Register an address to keep connected. Persists it if a store is configured.
void remove(const Address &address)
Stop reconnecting to an address: drops it as a target and from the store.
void attach(NodeContext &ctx) override
A pluggable network subsystem.
Definition node.h:65
A lightweight handle to a connected peer.
Self-certifying peer identity.
The narrow contract a subsystem needs from the node — and nothing more.
size_t max_targets
cap on ACTIVE re-dial targets (bounds memory + dial fan-out)
size_t startup_targets
on start, actively re-dial this many best peers from the book
std::chrono::milliseconds base_backoff
std::chrono::milliseconds max_backoff
size_t max_attempts
give up actively dialing a target after this many consecutive failures; 0 = retry forever
std::chrono::milliseconds tick
bool persist_discovered
remember dialed peers automatically
std::chrono::milliseconds dial_timeout
assume an in-flight dial is dead after this if no connect/fail event arrives (backstop only)
size_t archive_max
cap on the persistent peer book (history of everyone we met)
std::string store_path
persist the peer book here (empty = memory only)
std::chrono::seconds archive_max_age
forget peers unseen this long (30 days)