From c03ca13f1768e3d4d842a40c5a5afaa3d53aa1e1 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 30 Apr 2018 08:51:03 -0700 Subject: [PATCH] modules/federation/federation: Add feds backfill event grid w/ cmd. --- modules/console.cc | 37 ++++++++++++ modules/federation/federation.cc | 98 ++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/modules/console.cc b/modules/console.cc index b73be179b..516d5791a 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -3513,6 +3513,43 @@ console_cmd__feds__head(opt &out, const string_view &line) return true; } +bool +console_cmd__feds__backfill(opt &out, const string_view &line) +{ + const params param{line, " ", + { + "room_id", "event_id", "[limit]" + }}; + + const auto &room_id + { + m::room_id(param.at(0)) + }; + + const m::event::id &event_id + { + param.at(1) + }; + + const size_t limit + { + param.at(2, size_t(4)) + }; + + using prototype = void (const m::room::id &, + const m::event::id &, + const size_t &, + std::ostream &); + + static m::import feds__backfill + { + "federation_federation", "feds__backfill" + }; + + feds__backfill(room_id, event_id, limit, out); + return true; +} + bool console_cmd__feds__resend(opt &out, const string_view &line) { diff --git a/modules/federation/federation.cc b/modules/federation/federation.cc index af20e5b77..b0d100948 100644 --- a/modules/federation/federation.cc +++ b/modules/federation/federation.cc @@ -269,3 +269,101 @@ feds__head(const m::room::id &room_id, return; } + +extern "C" void +feds__backfill(const m::room::id &room_id, + const m::event::id &event_id, + const size_t &limit, + std::ostream &out) +{ + struct req + :m::v1::backfill + { + char origin[256]; + char buf[16_KiB]; + + req(const m::room::id &room_id, const m::event::id &event_id, const string_view &origin, const size_t &limit) + :m::v1::backfill{[&] + { + m::v1::backfill::opts opts; + opts.remote = string_view{this->origin, strlcpy(this->origin, origin)}; + opts.event_id = event_id; + opts.limit = limit; + opts.dynamic = true; + return m::v1::backfill{room_id, mutable_buffer{buf}, std::move(opts)}; + }()} + {} + }; + + std::list reqs; + const m::room::origins origins{room_id}; + origins.for_each([&out, &room_id, &event_id, &limit, &reqs] + (const string_view &origin) + { + const auto emsg + { + ircd::server::errmsg(origin) + }; + + if(!emsg) try + { + reqs.emplace_back(room_id, event_id, origin, limit); + } + catch(const std::exception &e) + { + return; + } + }); + + auto all + { + ctx::when_all(begin(reqs), end(reqs)) + }; + + all.wait(30s, std::nothrow); + + std::map> grid; + + for(auto &req : reqs) try + { + if(req.wait(1ms, std::nothrow)) + { + const auto code{req.get()}; + const json::object &response{req}; + const json::array pdus + { + response.at("pdus") + }; + + for(const json::object &pdu : pdus) + { + const auto &event_id + { + unquote(pdu.at("event_id")) + }; + + grid[event_id].emplace(&req); + } + } + else cancel(req); + } + catch(const std::exception &e) + { + out << "- " << req.origin << " " << e.what() << std::endl; + } + + size_t i(0); + for(const auto &p : grid) + out << i++ << " " << p.first << std::endl; + + for(size_t j(0); j < i; ++j) + out << "| " << j << " "; + out << "|" << std::endl; + + for(const auto &req : reqs) + { + for(const auto &p : grid) + out << "| " << (p.second.count(&req)? '+' : ' ') << " "; + out << "| " << req.origin << std::endl; + } +}