// The Construct // // Copyright (C) The Construct Developers, Authors & Contributors // Copyright (C) 2016-2020 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_M_GOSSIP_H namespace ircd::m { struct gossip; } /// Matrix Gossip is a mechanism that proactively resolves the head (forward- /// extremities) of a room on remote servers by sending the events they are /// missing if we have them. Gossip may be performed multiple times, checking /// for changes in the remote head and repeating based on options or until /// completion. struct ircd::m::gossip :instance_list { struct opts; struct result; static log::log log; const struct opts &opts; std::list requests; std::set attempts; private: bool full() const noexcept; bool started(const event::id &, const string_view &) const; bool handle(result &); bool handle(); bool start(const event::id &, const string_view &); bool submit(const event::id &, const string_view &); bool handle_head(const m::event &); bool gossip_head(); public: gossip(const struct opts &); gossip(const gossip &) = delete; gossip &operator=(const gossip &) = delete; ~gossip() noexcept; }; template<> decltype(ircd::m::gossip::list) ircd::instance_list::list; struct ircd::m::gossip::opts { /// Room apropos; when room.event_id is true, only that event will be /// the subject of gossip and that is only if the remote's head requires /// it. room.event_id should not be given in most cases. m::room room; /// When hint_only=true this string is used to conduct gossip with the /// single remote given. string_view hint; /// Forces remote operations to the remote given in the hint only. bool hint_only {false}; /// Depthwise window of gossip: no gossip for events outside of a given /// depth window. Ignored if !depth.second. pair depth {0, 0}; /// Indexwise window of gossip: no gossip for events with a value outside /// of the window. pair ref {0, -1UL}; /// The number of rounds the algorithm runs for. size_t rounds {-1UL}; /// Total event limit over all operations. size_t max {-1UL}; /// Limit the number of gossips in flight at any given time. size_t width {128}; }; struct ircd::m::gossip::result { unique_mutable_buffer buf; string_view txn; string_view txnid; string_view remote; event::id event_id; m::fed::send request; };