diff --git a/include/ircd/m/room/aliases.h b/include/ircd/m/room/aliases.h index 64754934c..ec8325fbd 100644 --- a/include/ircd/m/room/aliases.h +++ b/include/ircd/m/room/aliases.h @@ -46,8 +46,11 @@ struct ircd::m::room::aliases::cache static bool for_each(const string_view &server, const closure_bool &); static bool for_each(const closure_bool &); static bool has(const alias &); + static void fetch(const alias &, const net::hostport &remote); + static bool fetch(std::nothrow_t, const alias &, const net::hostport &remote); static bool get(std::nothrow_t, const alias &, const id::closure &); static void get(const alias &, const id::closure &); + static id::buf get(std::nothrow_t, const alias &); static id::buf get(const alias &); static bool set(const alias &, const id &); static bool del(const alias &); diff --git a/ircd/m_room.cc b/ircd/m_room.cc index 98fd5cebc..25563b46d 100644 --- a/ircd/m_room.cc +++ b/ircd/m_room.cc @@ -2469,11 +2469,63 @@ ircd::m::room::aliases::cache::set(const alias &a, return call(a, i); } +bool +ircd::m::room::aliases::cache::fetch(std::nothrow_t, + const alias &a, + const net::hostport &hp) +try +{ + fetch(a, hp); + return true; +} +catch(const std::exception &e) +{ + thread_local char buf[384]; + log::error + { + log, "Failed to fetch room_id for %s from %s :%s", + string_view{a}, + string(buf, hp), + e.what(), + }; + + return false; +} + +void +ircd::m::room::aliases::cache::fetch(const alias &a, + const net::hostport &hp) +{ + using prototype = void (const alias &, const net::hostport &); + + static mods::import call + { + "m_room_aliases", "ircd::m::room::aliases::cache::fetch" + }; + + return call(a, hp); +} + ircd::m::room::id::buf ircd::m::room::aliases::cache::get(const alias &a) { id::buf ret; - get(a, [&ret](const id &room_id) + get(a, [&ret] + (const id &room_id) + { + ret = room_id; + }); + + return ret; +} + +ircd::m::room::id::buf +ircd::m::room::aliases::cache::get(std::nothrow_t, + const alias &a) +{ + id::buf ret; + get(std::nothrow, a, [&ret] + (const id &room_id) { ret = room_id; }); diff --git a/modules/m_room_aliases.cc b/modules/m_room_aliases.cc index b99b554db..c132da85e 100644 --- a/modules/m_room_aliases.cc +++ b/modules/m_room_aliases.cc @@ -35,6 +35,13 @@ alias_cache_ttl { "default", 604800L }, }; +conf::item +alias_fetch_timeout +{ + { "name", "ircd.m.room.aliases.fetch.timeout" }, + { "default", 10L }, +}; + // // m::room::aliases // @@ -98,7 +105,7 @@ ircd::m::room::aliases::cache::del(const alias &alias) const auto &event_idx { - alias_room.get("ircd.room.alias", key) + alias_room.get(std::nothrow, "ircd.room.alias", key) }; if(!event_idx) @@ -106,7 +113,7 @@ ircd::m::room::aliases::cache::del(const alias &alias) const auto event_id { - m::event_id(event_idx) + m::event_id(event_idx, std::nothrow) }; if(!event_id) @@ -154,22 +161,35 @@ ircd::m::room::aliases::cache::get(std::nothrow_t, alias.swap(swapbuf) }; - const auto &event_idx + m::event::idx event_idx { - alias_room.get("ircd.room.alias", key) + alias_room.get(std::nothrow, "ircd.room.alias", key) }; - bool ret{false}; if(!event_idx) - return ret; + { + if(!fetch(std::nothrow, alias, alias.host())) + return false; + + event_idx = alias_room.get(std::nothrow, "ircd.room.alias", key); + } time_t ts; if(!m::get(event_idx, "origin_server_ts", ts)) - return ret; + return false; if(ircd::time() - ts > seconds(alias_cache_ttl).count()) - return ret; + { + if(!fetch(std::nothrow, alias, alias.host())) + return false; + event_idx = alias_room.get(std::nothrow, "ircd.room.alias", key); + } + + if(!event_idx) + return false; + + bool ret{false}; m::get(std::nothrow, event_idx, "content", [&closure, &ret] (const json::object &content) { @@ -271,7 +291,7 @@ ircd::m::room::aliases::cache::has(const alias &alias) const auto &event_idx { - alias_room.get("ircd.room.alias", key) + alias_room.get(std::nothrow, "ircd.room.alias", key) }; if(!event_idx)