From c27e911d267b92eb66f3596efdca0ea71771c431 Mon Sep 17 00:00:00 2001 From: Jason Volk <jason@zemos.net> Date: Wed, 28 Feb 2018 20:42:47 -0800 Subject: [PATCH] modules/client/directory/room: Create and use the !alias room to cache room alias queries. --- modules/client/directory/room.cc | 106 ++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 23 deletions(-) diff --git a/modules/client/directory/room.cc b/modules/client/directory/room.cc index 3f29c7949..7214302b9 100644 --- a/modules/client/directory/room.cc +++ b/modules/client/directory/room.cc @@ -16,6 +16,12 @@ IRCD_MODULE "Client 7.2 :Room aliases" }; +const ircd::m::room::id::buf +alias_room_id +{ + "alias", ircd::my_host() +}; + resource directory_room_resource { @@ -94,20 +100,78 @@ directory_room_put directory_room_resource, "PUT", put__directory_room }; + +static json::object +room_alias_fetch(const mutable_buffer &out, + const m::id::room_alias &alias); + +/// Translate a room alias into a room_id. This function first checks the +/// local cache. A cache miss will then cause in a query to the remote, the +/// result of which will be added to cache. m::id::room room_id__room_alias(const mutable_buffer &out, const m::id::room_alias &alias) { - //TODO: XXX cache strat + m::id::room ret; + const auto cache_closure{[&out, &ret] + (const m::event &event) + { + const string_view &room_id + { + unquote(at<"content"_>(event).get("room_id")) + }; + if(room_id) + { + copy(out, room_id); + ret = out; + } + }}; + + const m::room alias_room{alias_room_id}; + alias_room.get(std::nothrow, "ircd.alias", alias, cache_closure); + if(ret) + return ret; + + // Buf has to hold our output headers, their received headers, and + // the received aliasing content. const unique_buffer<mutable_buffer> buf { - 8_KiB //TODO: XXX + 32_KiB }; + const json::object &response + { + room_alias_fetch(buf, alias) + }; + + // Cache the result + send(alias_room, m::me.user_id, "ircd.alias", alias, response); + + const m::id::room &room_id + { + unquote(response.at("room_id")) + }; + + return m::room::id + { + string_view + { + data(out), copy(out, room_id) + } + }; +} + +/// This function makes a room alias request to a remote. The alias +/// room cache is not checked or updated from here, this is only the +/// query operation. +json::object +room_alias_fetch(const mutable_buffer &out, + const m::id::room_alias &alias) +{ m::v1::query::directory federation_request { - alias, buf + alias, out }; //TODO: conf @@ -127,24 +191,20 @@ room_id__room_alias(const mutable_buffer &out, federation_request }; - if(empty(response["room_id"])) - throw m::NOT_FOUND{}; - - if(empty(response["servers"])) - throw m::NOT_FOUND{}; - - const auto &room_id - { - unquote(response.at("room_id")) - }; - - //TODO: XXX cache strat - - return m::room::id - { - string_view - { - data(out), copy(out, room_id) - } - }; + return response; } + +const m::hook +_create_alias_room +{ + { + { "_site", "vm notify" }, + { "room_id", "!ircd:zemos.net" }, + { "type", "m.room.create" }, + }, + + [](const m::event &) + { + m::create(alias_room_id, m::me.user_id); + } +};