0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-26 05:48:20 +02:00

modules/m_bridge: Add initialization; worker spawn; cached error handling.

This commit is contained in:
Jason Volk 2021-02-03 05:02:11 -08:00
parent 207997ac95
commit 32bd0d7764

View file

@ -11,13 +11,14 @@
namespace ircd::m::bridge namespace ircd::m::bridge
{ {
static size_t make_txn(const config &, json::stack &, events::range &); static size_t make_txn(const config &, json::stack &, events::range &);
static event::idx worker_handle(const config &, const rfc3986::uri &, const events::range &, window_buffer); static event::idx worker_handle(const config &, const net::hostport &, const events::range &, window_buffer);
static void worker_loop(const config &, const rfc3986::uri &, const mutable_buffer &); static void worker_loop(const config &, const rfc3986::uri &, const mutable_buffer &);
static void worker(std::string config); static void worker(std::string event, std::string event_id);
static void handle_event(const event &, vm::eval &); static void handle_event(const event &, vm::eval &);
static void fini(); static void fini();
static void init(); static void init();
extern conf::item<bool> enable;
extern conf::item<seconds> timeout; extern conf::item<seconds> timeout;
extern ctx::dock worker_dock; extern ctx::dock worker_dock;
extern std::vector<context> worker_context; extern std::vector<context> worker_context;
@ -32,6 +33,13 @@ IRCD_MODULE
ircd::m::bridge::fini, ircd::m::bridge::fini,
}; };
decltype(ircd::m::bridge::enable)
ircd::m::bridge::enable
{
{ "name", "ircd.m.bridge.enable" },
{ "default", true },
};
decltype(ircd::m::bridge::timeout) decltype(ircd::m::bridge::timeout)
ircd::m::bridge::timeout ircd::m::bridge::timeout
{ {
@ -54,22 +62,6 @@ ircd::m::bridge::notify_hook
} }
}; };
void
ircd::m::bridge::init()
{
}
void
ircd::m::bridge::fini()
{
for(auto &worker : worker_context)
worker.terminate();
for(auto &worker : worker_context)
worker.join();
}
void void
ircd::m::bridge::handle_event(const m::event &event, ircd::m::bridge::handle_event(const m::event &event,
vm::eval &eval) vm::eval &eval)
@ -98,12 +90,64 @@ catch(const std::exception &e)
} }
void void
ircd::m::bridge::worker(std::string config_) ircd::m::bridge::init()
{
if(!enable)
return;
config::for_each([]
(const event::idx &event_idx, const event &event, const config &config)
{
log::debug
{
log, "Found configuration for '%s' in %s by %s",
json::get<"id"_>(config),
json::get<"room_id"_>(event),
string_view{event.event_id},
};
worker_context.emplace_back(context
{
"m.bridge",
512_KiB,
context::POST,
std::bind(&bridge::worker, std::string(event.source), std::string(event.event_id)),
});
return true;
});
}
void
ircd::m::bridge::fini()
{
for(auto &worker : worker_context)
worker.terminate();
if(!worker_context.empty())
log::debug
{
log, "Waiting for %zu bridge workers...",
worker_context.size(),
};
for(auto &worker : worker_context)
worker.join();
}
void
ircd::m::bridge::worker(const std::string event_,
const std::string event_id)
try try
{ {
const m::event event
{
json::object{event_}, event_id
};
const bridge::config config const bridge::config config
{ {
config_ json::get<"content"_>(event)
}; };
const rfc3986::uri uri const rfc3986::uri uri
@ -116,8 +160,29 @@ try
event::MAX_SIZE * 8 event::MAX_SIZE * 8
}; };
// Wait for run::level RUN before entering work loop. log::notice
{
log, "Bridging to '%s' via %s by %s",
json::get<"id"_>(config),
uri.remote,
event_id,
};
run::barrier<ctx::interrupted> {}; run::barrier<ctx::interrupted> {};
const bool prelinking
{
server::prelink(uri.remote)
};
if(!prelinking)
log::warning
{
log, "Bridging to '%s' via %s may not be possible :%s",
json::get<"id"_>(config),
uri.remote,
server::errmsg(uri.remote),
};
worker_loop(config, uri, buf); worker_loop(config, uri, buf);
} }
catch(const ctx::interrupted &) catch(const ctx::interrupted &)
@ -139,6 +204,11 @@ ircd::m::bridge::worker_loop(const config &config,
const mutable_buffer &buf) const mutable_buffer &buf)
try try
{ {
const net::hostport target
{
uri.remote
};
auto since {vm::sequence::retired}; do auto since {vm::sequence::retired}; do
{ {
worker_dock.wait([&since] worker_dock.wait([&since]
@ -146,18 +216,36 @@ try
return since < vm::sequence::retired; return since < vm::sequence::retired;
}); });
// Wait here if the bridge is down.
while(unlikely(server::errant(target)))
{
log::error
{
log, "Waiting for '%s' at %s with error :%s",
json::get<"id"_>(config),
uri.remote,
server::errmsg(target),
};
sleep(15s);
continue;
}
const events::range range const events::range range
{ {
since, vm::sequence::retired + 1 since, vm::sequence::retired + 1
}; };
since = worker_handle(config, uri, range, buf); since = worker_handle(config, target, range, buf);
assert(since >= range.first); assert(since >= range.first);
assert(since <= range.second); assert(since <= range.second);
// Prevent spin for retrying the same range on handled exception. // Prevent spin for retrying the same range on handled exception.
if(unlikely(since == range.first)) if(unlikely(since == range.first))
{
sleep(15s); sleep(15s);
continue;
}
} }
while(run::level == run::level::RUN); while(run::level == run::level::RUN);
} }
@ -176,7 +264,7 @@ catch(const std::exception &e)
ircd::m::event::idx ircd::m::event::idx
ircd::m::bridge::worker_handle(const config &config, ircd::m::bridge::worker_handle(const config &config,
const rfc3986::uri &uri, const net::hostport &target,
const events::range &range_, const events::range &range_,
window_buffer buf) window_buffer buf)
try try
@ -229,11 +317,6 @@ try
count, count,
}; };
const net::hostport target
{
uri.remote
};
// HTTP request sans // HTTP request sans
http::request http::request
{ {