0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-13 15:38:57 +02:00

ircd: Move m::import to mods::import where it is more appropriate.

This commit is contained in:
Jason Volk 2018-09-13 18:02:10 -07:00
parent 75a05d864c
commit 11948e47ac
15 changed files with 225 additions and 248 deletions

View file

@ -358,7 +358,7 @@ try
// function does a lot of IO so it requires an ircd::ctx. // function does a lot of IO so it requires an ircd::ctx.
ircd::context{[] ircd::context{[]
{ {
ircd::m::import<void ()> reload_conf ircd::mods::import<void ()> reload_conf
{ {
"s_conf", "reload_conf" "s_conf", "reload_conf"
}; };

View file

@ -1,103 +0,0 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// 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_IMPORT_H
namespace ircd::m
{
template<class prototype> struct import;
struct imports extern imports;
}
struct ircd::m::imports
:std::map<std::string, ircd::module, std::less<>>
{
void init();
};
template<class prototype>
struct ircd::m::import
:mods::import<prototype>
{
std::string modname;
std::string symname;
void reload();
public:
template<class... args> auto operator()(args&&... a);
prototype *operator->();
prototype &operator*();
operator prototype &();
import(std::string modname, std::string symname);
};
template<class prototype>
ircd::m::import<prototype>::import(std::string modname,
std::string symname)
:mods::import<prototype>{}
,modname{std::move(modname)}
,symname{std::move(symname)}
{}
template<class prototype>
ircd::m::import<prototype>::operator
prototype &()
{
return this->operator*();
}
template<class prototype>
prototype &
ircd::m::import<prototype>::operator*()
{
return *this->operator->();
}
template<class prototype>
prototype *
ircd::m::import<prototype>::operator->()
{
if(unlikely(!*this))
reload();
return mods::import<prototype>::operator->();
}
template<class prototype>
template<class... args>
auto
ircd::m::import<prototype>::operator()(args&&... a)
{
if(unlikely(!*this))
reload();
return mods::import<prototype>::operator()(std::forward<args>(a)...);
}
template<class prototype>
void
ircd::m::import<prototype>::reload()
try
{
auto &import(static_cast<mods::import<prototype> &>(*this));
import = { imports.at(modname), symname };
}
catch(const std::out_of_range &e)
{
throw m::UNAVAILABLE
{
"Sorry, %s in %s is currently unavailable.",
symname,
modname
};
}

View file

@ -30,7 +30,6 @@ namespace ircd::m::vm
#include "name.h" #include "name.h"
#include "error.h" #include "error.h"
#include "import.h"
#include "self.h" #include "self.h"
#include "id.h" #include "id.h"
#include "event.h" #include "event.h"

View file

@ -14,14 +14,25 @@
namespace ircd::mods namespace ircd::mods
{ {
template<class T> struct import; template<class T> struct import;
struct imports extern imports;
} }
struct ircd::mods::imports
:std::map<std::string, mods::module, std::less<>>
{};
/// Representation of a symbol in a loaded shared library /// Representation of a symbol in a loaded shared library
/// ///
template<class T> template<class T>
struct ircd::mods::import struct ircd::mods::import
:sym_ptr :sym_ptr
{ {
std::string module_name;
std::string symbol_name;
void reload();
public:
template<class... args> auto operator()(args&&... a) const; template<class... args> auto operator()(args&&... a) const;
template<class... args> auto operator()(args&&... a); template<class... args> auto operator()(args&&... a);
@ -33,26 +44,67 @@ struct ircd::mods::import
T &operator*(); T &operator*();
operator T &(); operator T &();
using sym_ptr::sym_ptr; explicit import(const mods::module &, std::string symbol_name);
import(std::string module_name, std::string symbol_name);
}; };
template<class T> template<class T>
ircd::mods::import<T>::operator T &() ircd::mods::import<T>::import(std::string module_name,
std::string symbol_name)
:sym_ptr
{ {
return sym_ptr::operator*<T>(); // Note sym_ptr is purposely default constructed; this makes the import
// "lazy" and will be loaded via miss on first use. This is useful in
// the general use-case of static construction.
}
,module_name
{
std::move(module_name)
}
,symbol_name
{
std::move(symbol_name)
}
{}
template<class T>
ircd::mods::import<T>::import(const mods::module &module,
std::string symbol_name)
:sym_ptr
{
module, symbol_name
}
,module_name
{
module.name()
}
,symbol_name
{
std::move(symbol_name)
}
{}
template<class T>
ircd::mods::import<T>::operator
T &()
{
return this->operator*();
} }
template<class T> template<class T>
T & T &
ircd::mods::import<T>::operator*() ircd::mods::import<T>::operator*()
{ {
return sym_ptr::operator*<T>(); return *this->operator->();
} }
template<class T> template<class T>
T * T *
ircd::mods::import<T>::operator->() ircd::mods::import<T>::operator->()
{ {
if(unlikely(!*this))
reload();
return sym_ptr::operator-><T>(); return sym_ptr::operator-><T>();
} }
@ -61,7 +113,7 @@ ircd::mods::import<T>::operator
const T &() const T &()
const const
{ {
return sym_ptr::operator*<T>(); return this->operator*();
} }
template<class T> template<class T>
@ -69,7 +121,7 @@ const T &
ircd::mods::import<T>::operator*() ircd::mods::import<T>::operator*()
const const
{ {
return sym_ptr::operator*<T>(); return this->operator->();
} }
template<class T> template<class T>
@ -85,6 +137,9 @@ template<class... args>
auto auto
ircd::mods::import<T>::operator()(args&&... a) ircd::mods::import<T>::operator()(args&&... a)
{ {
if(unlikely(!*this))
reload();
return sym_ptr::operator()<T>(std::forward<args>(a)...); return sym_ptr::operator()<T>(std::forward<args>(a)...);
} }
@ -96,3 +151,30 @@ const
{ {
return sym_ptr::operator()<T>(std::forward<args>(a)...); return sym_ptr::operator()<T>(std::forward<args>(a)...);
} }
template<class T>
void
ircd::mods::import<T>::reload()
try
{
auto &module
{
imports.at(module_name)
};
auto &sp
{
static_cast<sym_ptr &>(*this)
};
sp = { module, symbol_name };
}
catch(const std::out_of_range &e)
{
throw unavailable
{
"Sorry, %s in %s is currently unavailable.",
symbol_name,
module_name
};
}

View file

@ -21,6 +21,7 @@ namespace ircd::mods
IRCD_EXCEPTION(error, invalid_export) IRCD_EXCEPTION(error, invalid_export)
IRCD_EXCEPTION(error, expired_symbol) IRCD_EXCEPTION(error, expired_symbol)
IRCD_EXCEPTION(error, undefined_symbol) IRCD_EXCEPTION(error, undefined_symbol)
IRCD_EXCEPTION(expired_symbol, unavailable)
string_view name(const mod &); string_view name(const mod &);
string_view path(const mod &); string_view path(const mod &);

View file

@ -24,7 +24,7 @@ ircd::m::pretty(std::ostream &s,
const event &e) const event &e)
{ {
using prototype = void (std::ostream &, const event &); using prototype = void (std::ostream &, const event &);
static import<prototype> pretty thread_local mods::import<prototype> pretty
{ {
"m_event", "pretty__event" "m_event", "pretty__event"
}; };
@ -51,7 +51,7 @@ ircd::m::pretty_oneline(std::ostream &s,
const bool &content_keys) const bool &content_keys)
{ {
using prototype = void (std::ostream &, const event &, const bool &); using prototype = void (std::ostream &, const event &, const bool &);
static import<prototype> pretty_oneline thread_local mods::import<prototype> pretty_oneline
{ {
"m_event", "pretty_oneline__event" "m_event", "pretty_oneline__event"
}; };
@ -76,7 +76,7 @@ ircd::m::pretty_msgline(std::ostream &s,
const event &e) const event &e)
{ {
using prototype = void (std::ostream &, const event &); using prototype = void (std::ostream &, const event &);
static import<prototype> pretty_msgline thread_local mods::import<prototype> pretty_msgline
{ {
"m_event", "pretty_msgline__event" "m_event", "pretty_msgline__event"
}; };
@ -101,7 +101,7 @@ ircd::m::pretty(std::ostream &s,
const event::prev &prev) const event::prev &prev)
{ {
using prototype = void (std::ostream &, const event &); using prototype = void (std::ostream &, const event &);
static import<prototype> pretty thread_local mods::import<prototype> pretty
{ {
"m_event", "pretty__prev" "m_event", "pretty__prev"
}; };
@ -126,7 +126,7 @@ ircd::m::pretty_oneline(std::ostream &s,
const event::prev &prev) const event::prev &prev)
{ {
using prototype = void (std::ostream &, const event::prev &); using prototype = void (std::ostream &, const event::prev &);
static import<prototype> pretty_oneline thread_local mods::import<prototype> pretty_oneline
{ {
"m_event", "pretty_oneline__prev" "m_event", "pretty_oneline__prev"
}; };

View file

@ -53,8 +53,6 @@ catch(const m::error &e)
{ {
log, "%s %s", e.what(), e.content log, "%s %s", e.what(), e.content
}; };
assert(m::imports.empty());
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
@ -62,8 +60,6 @@ catch(const std::exception &e)
{ {
log, "%s", e.what() log, "%s", e.what()
}; };
assert(m::imports.empty());
} }
ircd::m::init::~init() ircd::m::init::~init()
@ -72,7 +68,7 @@ noexcept try
if(!std::current_exception()) if(!std::current_exception())
presence::set(me, "offline", me_offline_status_msg); presence::set(me, "offline", me_offline_status_msg);
m::imports.clear(); mods::imports.clear();
} }
catch(const m::error &e) catch(const m::error &e)
{ {
@ -87,20 +83,20 @@ catch(const m::error &e)
void void
ircd::m::init::close() ircd::m::init::close()
{ {
m::imports.erase("s_listen"s); mods::imports.erase("s_listen"s);
} }
void void
ircd::m::init::init_keys() ircd::m::init::init_keys()
try try
{ {
m::imports.emplace("s_keys"s, "s_keys"s); mods::imports.emplace("s_keys"s, "s_keys"s);
const unwind::exceptional uw{[] const unwind::exceptional uw{[]
{ {
m::imports.erase("s_keys"s); mods::imports.erase("s_keys"s);
}}; }};
m::import<void ()> init_my_keys mods::import<void ()> init_my_keys
{ {
"s_keys", "init_my_keys" "s_keys", "init_my_keys"
}; };
@ -132,14 +128,33 @@ try
return; return;
} }
m::imports.init(); // Manually load first modules
mods::imports.emplace("vm"s, "vm"s);
mods::imports.emplace("vm_fetch"s, "vm_fetch"s);
// The order of these prefixes will be the loading order. Order of
// specific modules within a prefix is not determined here.
static const string_view prefixes[]
{
"s_", "m_", "key_", "media_", "client_", "federation_"
};
// Load modules by prefix.
for(const auto &prefix : prefixes)
for(const auto &name : mods::available())
if(startswith(name, prefix))
mods::imports.emplace(name, name);
// Manually load last modules
mods::imports.emplace("webroot"s, "webroot"s);
if(db::sequence(*dbs::events) == 0) if(db::sequence(*dbs::events) == 0)
bootstrap(); bootstrap();
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
const ctx::exception_handler eh; const ctx::exception_handler eh;
m::imports.clear(); mods::imports.clear();
throw m::error throw m::error
{ {
"M_INIT_ERROR", "%s", e.what() "M_INIT_ERROR", "%s", e.what()
@ -148,7 +163,7 @@ catch(const std::exception &e)
catch(const ctx::terminated &) catch(const ctx::terminated &)
{ {
const ctx::exception_handler eh; const ctx::exception_handler eh;
m::imports.clear(); mods::imports.clear();
throw ctx::terminated{}; throw ctx::terminated{};
} }
@ -370,7 +385,7 @@ ircd::m::feds::state::state(const m::room::id &room_id,
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__state thread_local mods::import<prototype> feds__state
{ {
"federation_federation", "feds__state" "federation_federation", "feds__state"
}; };
@ -614,7 +629,7 @@ ircd::m::vm::eval::operator()(const room &room,
{ {
using prototype = fault (eval &, const m::room &, json::iov &, const json::iov &); using prototype = fault (eval &, const m::room &, json::iov &, const json::iov &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"vm", "eval__commit_room" "vm", "eval__commit_room"
}; };
@ -630,7 +645,7 @@ ircd::m::vm::eval::operator()(json::iov &event,
{ {
using prototype = fault (eval &, json::iov &, const json::iov &); using prototype = fault (eval &, json::iov &, const json::iov &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"vm", "eval__commit" "vm", "eval__commit"
}; };
@ -644,7 +659,7 @@ try
{ {
using prototype = fault (eval &, const m::event &); using prototype = fault (eval &, const m::event &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"vm", "eval__event" "vm", "eval__event"
}; };
@ -738,7 +753,7 @@ ircd::m::verify(const m::keys &keys)
{ {
using prototype = bool (const m::keys &) noexcept; using prototype = bool (const m::keys &) noexcept;
static import<prototype> function thread_local mods::import<prototype> function
{ {
"s_keys", "verify__keys" "s_keys", "verify__keys"
}; };
@ -764,7 +779,7 @@ ircd::m::keys::get(const string_view &server_name,
{ {
using prototype = void (const string_view &, const string_view &, const closure &); using prototype = void (const string_view &, const string_view &, const closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"s_keys", "get__keys" "s_keys", "get__keys"
}; };
@ -779,7 +794,7 @@ ircd::m::keys::query(const string_view &query_server,
{ {
using prototype = bool (const string_view &, const queries &, const closure_bool &); using prototype = bool (const string_view &, const queries &, const closure_bool &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"s_keys", "query__keys" "s_keys", "query__keys"
}; };
@ -816,7 +831,7 @@ ircd::m::visible(const event &event,
{ {
using prototype = bool (const m::event &, const string_view &); using prototype = bool (const m::event &, const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"m_room_history_visibility", "visible" "m_room_history_visibility", "visible"
}; };
@ -845,7 +860,7 @@ ircd::m::receipt::read(const id::room &room_id,
{ {
using prototype = event::id::buf (const id::room &, const id::user &, const id::event &, const time_t &); using prototype = event::id::buf (const id::room &, const id::user &, const id::event &, const time_t &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "commit__m_receipt_m_read" "client_rooms", "commit__m_receipt_m_read"
}; };
@ -876,7 +891,7 @@ ircd::m::receipt::read(const id::room &room_id,
{ {
using prototype = bool (const id::room &, const id::user &, const id::event::closure &); using prototype = bool (const id::room &, const id::user &, const id::event::closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"m_receipt", "last_receipt__event_id" "m_receipt", "last_receipt__event_id"
}; };
@ -894,7 +909,7 @@ ircd::m::typing::set(const m::typing &object)
{ {
using prototype = event::id::buf (const m::typing &); using prototype = event::id::buf (const m::typing &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "commit__m_typing" "client_rooms", "commit__m_typing"
}; };
@ -934,7 +949,7 @@ ircd::m::presence::set(const presence &object)
{ {
using prototype = event::id::buf (const presence &); using prototype = event::id::buf (const presence &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"m_presence", "commit__m_presence" "m_presence", "commit__m_presence"
}; };
@ -998,7 +1013,7 @@ ircd::m::presence::get(std::nothrow_t,
{ {
using prototype = bool (std::nothrow_t, const m::user &, const event_closure &); using prototype = bool (std::nothrow_t, const m::user &, const event_closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"m_presence", "get__m_presence" "m_presence", "get__m_presence"
}; };
@ -1011,7 +1026,7 @@ ircd::m::presence::valid_state(const string_view &state)
{ {
using prototype = bool (const string_view &); using prototype = bool (const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"m_presence", "presence_valid_state" "m_presence", "presence_valid_state"
}; };
@ -1047,7 +1062,7 @@ ircd::m::create(const id::node &node_id,
{ {
using prototype = node (const id::node &, const json::members &); using prototype = node (const id::node &, const json::members &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"s_node", "create_node" "s_node", "create_node"
}; };
@ -1061,7 +1076,7 @@ ircd::m::exists(const node::id &node_id)
{ {
using prototype = bool (const node::id &); using prototype = bool (const node::id &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"s_node", "exists__nodeid" "s_node", "exists__nodeid"
}; };
@ -1598,7 +1613,7 @@ ircd::m::create(const id::user &user_id,
{ {
using prototype = user (const id::user &, const json::members &); using prototype = user (const id::user &, const json::members &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "user_create" "client_user", "user_create"
}; };
@ -1677,7 +1692,7 @@ ircd::m::user::activate()
{ {
using prototype = event::id::buf (const m::user &); using prototype = event::id::buf (const m::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_account", "activate__user" "client_account", "activate__user"
}; };
@ -1690,7 +1705,7 @@ ircd::m::user::deactivate()
{ {
using prototype = event::id::buf (const m::user &); using prototype = event::id::buf (const m::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_account", "deactivate__user" "client_account", "deactivate__user"
}; };
@ -1704,7 +1719,7 @@ const
{ {
using prototype = bool (const m::user &); using prototype = bool (const m::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_account", "is_active__user" "client_account", "is_active__user"
}; };
@ -1718,7 +1733,7 @@ ircd::m::user::filter(const json::object &filter,
{ {
using prototype = event::id::buf (const m::user &, const json::object &, const mutable_buffer &); using prototype = event::id::buf (const m::user &, const json::object &, const mutable_buffer &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "filter_set" "client_user", "filter_set"
}; };
@ -1775,7 +1790,7 @@ const
{ {
using prototype = bool (std::nothrow_t, const m::user &, const string_view &, const filter_closure &); using prototype = bool (std::nothrow_t, const m::user &, const string_view &, const filter_closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "filter_get" "client_user", "filter_get"
}; };
@ -1791,7 +1806,7 @@ ircd::m::user::account_data(const m::room &room,
{ {
using prototype = event::id::buf (const m::user &, const m::room &, const m::user &, const string_view &, const json::object &); using prototype = event::id::buf (const m::user &, const m::room &, const m::user &, const string_view &, const json::object &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "room_account_data_set" "client_user", "room_account_data_set"
}; };
@ -1806,7 +1821,7 @@ ircd::m::user::account_data(const m::user &sender,
{ {
using prototype = event::id::buf (const m::user &, const m::user &, const string_view &, const json::object &); using prototype = event::id::buf (const m::user &, const m::user &, const string_view &, const json::object &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "account_data_set" "client_user", "account_data_set"
}; };
@ -1882,7 +1897,7 @@ const
{ {
using prototype = void (const m::user &, const m::room &, const string_view &, const account_data_closure &); using prototype = void (const m::user &, const m::room &, const string_view &, const account_data_closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "room_account_data_get" "client_user", "room_account_data_get"
}; };
@ -1897,7 +1912,7 @@ const
{ {
using prototype = void (const m::user &, const string_view &, const account_data_closure &); using prototype = void (const m::user &, const string_view &, const account_data_closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "account_data_get" "client_user", "account_data_get"
}; };
@ -1911,7 +1926,7 @@ ircd::m::user::_account_data_type(const mutable_buffer &out,
{ {
using prototype = string_view (const mutable_buffer &, const m::room::id &); using prototype = string_view (const mutable_buffer &, const m::room::id &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_user", "room_account_data_type" "client_user", "room_account_data_type"
}; };
@ -1926,7 +1941,7 @@ ircd::m::user::profile(const m::user &sender,
{ {
using prototype = event::id::buf (const m::user &, const m::user &, const string_view &, const string_view &); using prototype = event::id::buf (const m::user &, const m::user &, const string_view &, const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_profile", "profile_set" "client_profile", "profile_set"
}; };
@ -1970,7 +1985,7 @@ const
{ {
using prototype = void (const m::user &, const string_view &, const profile_closure &); using prototype = void (const m::user &, const string_view &, const profile_closure &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_profile", "profile_get" "client_profile", "profile_get"
}; };
@ -1983,7 +1998,7 @@ ircd::m::user::password(const string_view &password)
{ {
using prototype = event::id::buf (const m::user::id &, const string_view &) noexcept; using prototype = event::id::buf (const m::user::id &, const string_view &) noexcept;
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_account", "set_password" "client_account", "set_password"
}; };
@ -1997,7 +2012,7 @@ const noexcept try
{ {
using prototype = bool (const m::user::id &, const string_view &) noexcept; using prototype = bool (const m::user::id &, const string_view &) noexcept;
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_account", "is_password" "client_account", "is_password"
}; };
@ -2473,7 +2488,7 @@ ircd::m::create(const id::room &room_id,
{ {
using prototype = room (const id::room &, const id::user &, const string_view &); using prototype = room (const id::room &, const id::user &, const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_createroom", "createroom__type" "client_createroom", "createroom__type"
}; };
@ -2489,7 +2504,7 @@ ircd::m::create(const id::room &room_id,
{ {
using prototype = room (const id::room &, const id::user &, const id::room &, const string_view &); using prototype = room (const id::room &, const id::user &, const id::room &, const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_createroom", "createroom__parent_type" "client_createroom", "createroom__parent_type"
}; };
@ -2503,7 +2518,7 @@ ircd::m::join(const id::room_alias &room_alias,
{ {
using prototype = event::id::buf (const id::room_alias &, const id::user &); using prototype = event::id::buf (const id::room_alias &, const id::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "join__alias_user" "client_rooms", "join__alias_user"
}; };
@ -2517,7 +2532,7 @@ ircd::m::join(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &); using prototype = event::id::buf (const m::room &, const id::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "join__room_user" "client_rooms", "join__room_user"
}; };
@ -2531,7 +2546,7 @@ ircd::m::leave(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &); using prototype = event::id::buf (const m::room &, const id::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "leave__room_user" "client_rooms", "leave__room_user"
}; };
@ -2546,7 +2561,7 @@ ircd::m::invite(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &, const id::user &); using prototype = event::id::buf (const m::room &, const id::user &, const id::user &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "invite__room_user" "client_rooms", "invite__room_user"
}; };
@ -2562,7 +2577,7 @@ ircd::m::redact(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &, const id::event &, const string_view &); using prototype = event::id::buf (const m::room &, const id::user &, const id::event &, const string_view &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "redact__" "client_rooms", "redact__"
}; };
@ -2655,7 +2670,7 @@ ircd::m::send(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &, const string_view &, const string_view &, const json::iov &); using prototype = event::id::buf (const m::room &, const id::user &, const string_view &, const string_view &, const json::iov &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "state__iov" "client_rooms", "state__iov"
}; };
@ -2693,7 +2708,7 @@ ircd::m::send(const room &room,
{ {
using prototype = event::id::buf (const m::room &, const id::user &, const string_view &, const json::iov &); using prototype = event::id::buf (const m::room &, const id::user &, const string_view &, const json::iov &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_rooms", "send__iov" "client_rooms", "send__iov"
}; };
@ -2771,7 +2786,7 @@ ircd::m::count_since(const room &r,
const event::idx &, const event::idx &,
const event::idx &); const event::idx &);
static m::import<prototype> _count_since thread_local mods::import<prototype> _count_since
{ {
"m_room", "count_since" "m_room", "count_since"
}; };
@ -2815,7 +2830,7 @@ ircd::m::room_id(const mutable_buffer &out,
{ {
using prototype = id::room (const mutable_buffer &, const id::room_alias &); using prototype = id::room (const mutable_buffer &, const id::room_alias &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_directory_room", "room_id__room_alias" "client_directory_room", "room_id__room_alias"
}; };
@ -2829,7 +2844,7 @@ ircd::m::exists(const id::room_alias &room_alias,
{ {
using prototype = bool (const id::room_alias, const bool &); using prototype = bool (const id::room_alias, const bool &);
static import<prototype> function thread_local mods::import<prototype> function
{ {
"client_directory_room", "room_alias_exists" "client_directory_room", "room_alias_exists"
}; };
@ -3540,39 +3555,6 @@ ircd::m::_hook_match(const m::event &matching,
return true; return true;
} }
///////////////////////////////////////////////////////////////////////////////
//
// m/import.h
//
decltype(ircd::m::imports)
ircd::m::imports
{};
void
ircd::m::imports::init()
{
// Manually load first modules
this->emplace("vm"s, "vm"s);
this->emplace("vm_fetch"s, "vm_fetch"s);
// The order of these prefixes will be the loading order. Order of
// specific modules within a prefix is not determined here.
static const string_view prefixes[]
{
"s_", "m_", "key_", "media_", "client_", "federation_"
};
// Load modules by prefix.
for(const auto &prefix : prefixes)
for(const auto &name : mods::available())
if(startswith(name, prefix))
this->emplace(name, name);
// Manually load last modules
this->emplace("webroot"s, "webroot"s);
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// m/error.h // m/error.h

View file

@ -1797,7 +1797,7 @@ const
const m::room::origins::closure &, const m::room::origins::closure &,
const m::room::origins::closure_bool &); const m::room::origins::closure_bool &);
static m::import<prototype> random_origin thread_local mods::import<prototype> random_origin
{ {
"m_room", "random_origin" "m_room", "random_origin"
}; };

View file

@ -197,6 +197,15 @@ ircd::mods::loaded(const string_view &name)
return mod::loaded.count(name); return mod::loaded.count(name);
} }
///////////////////////////////////////////////////////////////////////////////
//
// mods/import.h
//
decltype(ircd::mods::imports)
ircd::mods::imports
{};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// mods/sym_ptr.h // mods/sym_ptr.h

View file

@ -508,6 +508,13 @@ catch(const json::error &e)
http::BAD_REQUEST, "M_NOT_JSON", "%s", e.what() http::BAD_REQUEST, "M_NOT_JSON", "%s", e.what()
}; };
} }
catch(const mods::unavailable &e)
{
throw m::UNAVAILABLE
{
"%s", e.what()
};
}
catch(const std::out_of_range &e) catch(const std::out_of_range &e)
{ {
throw m::error throw m::error

View file

@ -599,7 +599,7 @@ console_cmd__conf__set(opt &out, const string_view &line)
const string_view &key, const string_view &key,
const string_view &val); const string_view &val);
static m::import<prototype> set_conf_item thread_local mods::import<prototype> set_conf_item
{ {
"s_conf", "set_conf_item" "s_conf", "set_conf_item"
}; };
@ -649,7 +649,7 @@ bool
console_cmd__conf__rehash(opt &out, const string_view &line) console_cmd__conf__rehash(opt &out, const string_view &line)
{ {
using prototype = void (const bool &); using prototype = void (const bool &);
static m::import<prototype> rehash_conf thread_local mods::import<prototype> rehash_conf
{ {
"s_conf", "rehash_conf" "s_conf", "rehash_conf"
}; };
@ -666,7 +666,7 @@ bool
console_cmd__conf__reload(opt &out, const string_view &line) console_cmd__conf__reload(opt &out, const string_view &line)
{ {
using prototype = void (); using prototype = void ();
static m::import<prototype> reload_conf thread_local mods::import<prototype> reload_conf
{ {
"s_conf", "reload_conf" "s_conf", "reload_conf"
}; };
@ -683,7 +683,7 @@ bool
console_cmd__conf__reset(opt &out, const string_view &line) console_cmd__conf__reset(opt &out, const string_view &line)
{ {
using prototype = void (); using prototype = void ();
static m::import<prototype> refresh_conf thread_local mods::import<prototype> refresh_conf
{ {
"s_conf", "refresh_conf" "s_conf", "refresh_conf"
}; };
@ -794,7 +794,7 @@ console_cmd__mod__reload(opt &out, const string_view &line)
for(auto it(names.begin()); it != names.end(); ++it) for(auto it(names.begin()); it != names.end(); ++it)
{ {
const auto &name{*it}; const auto &name{*it};
if(m::imports.erase(std::string{name})) if(mods::imports.erase(std::string{name}))
out << name << " unloaded." << std::endl; out << name << " unloaded." << std::endl;
else else
out << name << " is not loaded." << std::endl; out << name << " is not loaded." << std::endl;
@ -803,7 +803,7 @@ console_cmd__mod__reload(opt &out, const string_view &line)
for(auto it(names.rbegin()); it != names.rend(); ++it) for(auto it(names.rbegin()); it != names.rend(); ++it)
{ {
const auto &name{*it}; const auto &name{*it};
if(m::imports.emplace(std::string{name}, name).second) if(mods::imports.emplace(std::string{name}, name).second)
out << name << " loaded." << std::endl; out << name << " loaded." << std::endl;
else else
out << name << " is already loaded." << std::endl; out << name << " is already loaded." << std::endl;
@ -818,13 +818,13 @@ console_cmd__mod__load(opt &out, const string_view &line)
tokens(line, ' ', [&out] tokens(line, ' ', [&out]
(const string_view &name) (const string_view &name)
{ {
if(m::imports.find(name) != end(m::imports)) if(mods::imports.find(name) != end(mods::imports))
{ {
out << name << " is already loaded." << std::endl; out << name << " is already loaded." << std::endl;
return; return;
} }
m::imports.emplace(std::string{name}, name); mods::imports.emplace(std::string{name}, name);
out << name << " loaded." << std::endl; out << name << " loaded." << std::endl;
}); });
@ -837,7 +837,7 @@ console_cmd__mod__unload(opt &out, const string_view &line)
tokens(line, ' ', [&out] tokens(line, ' ', [&out]
(const string_view &name) (const string_view &name)
{ {
if(!m::imports.erase(std::string{name})) if(!mods::imports.erase(std::string{name}))
{ {
out << name << " is not loaded." << std::endl; out << name << " is not loaded." << std::endl;
return; return;
@ -2745,7 +2745,7 @@ console_cmd__net__listen__list(opt &out, const string_view &line)
{ {
using list = std::list<net::listener>; using list = std::list<net::listener>;
static m::import<list> listeners thread_local mods::import<list> listeners
{ {
"s_listen", "listeners" "s_listen", "listeners"
}; };
@ -2803,7 +2803,7 @@ console_cmd__net__listen__load(opt &out, const string_view &line)
{ {
using prototype = bool (const string_view &); using prototype = bool (const string_view &);
static m::import<prototype> load_listener thread_local mods::import<prototype> load_listener
{ {
"s_listen", "load_listener" "s_listen", "load_listener"
}; };
@ -2826,7 +2826,7 @@ console_cmd__net__listen__unload(opt &out, const string_view &line)
{ {
using prototype = bool (const string_view &); using prototype = bool (const string_view &);
static m::import<prototype> unload_listener thread_local mods::import<prototype> unload_listener
{ {
"s_listen", "unload_listener" "s_listen", "unload_listener"
}; };
@ -3007,7 +3007,7 @@ bool
console_cmd__key__crt__sign(opt &out, const string_view &line) console_cmd__key__crt__sign(opt &out, const string_view &line)
{ {
using prototype = void (const m::event &); using prototype = void (const m::event &);
static m::import<prototype> create_my_key thread_local mods::import<prototype> create_my_key
{ {
"s_keys", "create_my_key" "s_keys", "create_my_key"
}; };
@ -3168,7 +3168,7 @@ console_cmd__stage__make_prev(opt &out, const string_view &line)
const mutable_buffer &, const mutable_buffer &,
const size_t &, const size_t &,
const bool &); const bool &);
static m::import<prototype> make_prev__buf thread_local mods::import<prototype> make_prev__buf
{ {
"m_room", "make_prev__buf" "m_room", "make_prev__buf"
}; };
@ -3216,7 +3216,7 @@ console_cmd__stage__make_auth(opt &out, const string_view &line)
const vector_view<const string_view> &, const vector_view<const string_view> &,
const string_view &); const string_view &);
static m::import<prototype> make_auth__buf thread_local mods::import<prototype> make_auth__buf
{ {
"m_room", "make_auth__buf" "m_room", "make_auth__buf"
}; };
@ -3993,7 +3993,7 @@ console_cmd__event__fetch(opt &out, const string_view &line)
const m::event::id &, const m::event::id &,
const mutable_buffer &); const mutable_buffer &);
static m::import<prototype> acquire thread_local mods::import<prototype> acquire
{ {
"vm_fetch", "acquire" "vm_fetch", "acquire"
}; };
@ -4523,7 +4523,7 @@ console_cmd__room__head__rebuild(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &); using prototype = size_t (const m::room &);
static m::import<prototype> head__rebuild thread_local mods::import<prototype> head__rebuild
{ {
"m_room", "head__rebuild" "m_room", "head__rebuild"
}; };
@ -4551,7 +4551,7 @@ console_cmd__room__head__add(opt &out, const string_view &line)
}; };
using prototype = void (const m::event::id &, const db::op &, const bool &); using prototype = void (const m::event::id &, const db::op &, const bool &);
static m::import<prototype> head__modify thread_local mods::import<prototype> head__modify
{ {
"m_room", "head__modify" "m_room", "head__modify"
}; };
@ -4575,7 +4575,7 @@ console_cmd__room__head__del(opt &out, const string_view &line)
}; };
using prototype = void (const m::event::id &, const db::op &, const bool &); using prototype = void (const m::event::id &, const db::op &, const bool &);
static m::import<prototype> head__modify thread_local mods::import<prototype> head__modify
{ {
"m_room", "head__modify" "m_room", "head__modify"
}; };
@ -4604,7 +4604,7 @@ console_cmd__room__herd(opt &out, const string_view &line)
}; };
using prototype = void (const m::room &, const m::user &, const milliseconds &); using prototype = void (const m::room &, const m::user &, const milliseconds &);
static m::import<prototype> room_herd thread_local mods::import<prototype> room_herd
{ {
"m_room", "room_herd" "m_room", "room_herd"
}; };
@ -4633,7 +4633,7 @@ console_cmd__room__head__reset(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &); using prototype = size_t (const m::room &);
static m::import<prototype> head__reset thread_local mods::import<prototype> head__reset
{ {
"m_room", "head__reset" "m_room", "head__reset"
}; };
@ -4666,7 +4666,7 @@ console_cmd__room__complete(opt &out, const string_view &line)
}; };
using prototype = std::pair<bool, int64_t> (const m::room &); using prototype = std::pair<bool, int64_t> (const m::room &);
static m::import<prototype> is_complete thread_local mods::import<prototype> is_complete
{ {
"m_room", "is_complete" "m_room", "is_complete"
}; };
@ -5141,7 +5141,7 @@ console_cmd__room__state__force(opt &out, const string_view &line)
}; };
using prototype = bool (const m::event &); using prototype = bool (const m::event &);
static m::import<prototype> state__force_present thread_local mods::import<prototype> state__force_present
{ {
"m_room", "state__force_present" "m_room", "state__force_present"
}; };
@ -5174,7 +5174,7 @@ console_cmd__room__state__rebuild__present(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &); using prototype = size_t (const m::room &);
static m::import<prototype> state__rebuild_present thread_local mods::import<prototype> state__rebuild_present
{ {
"m_room", "state__rebuild_present" "m_room", "state__rebuild_present"
}; };
@ -5207,7 +5207,7 @@ console_cmd__room__state__rebuild__history(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &); using prototype = size_t (const m::room &);
static m::import<prototype> state__rebuild_history thread_local mods::import<prototype> state__rebuild_history
{ {
"m_room", "state__rebuild_history" "m_room", "state__rebuild_history"
}; };
@ -5731,7 +5731,7 @@ console_cmd__room__purge(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &); using prototype = size_t (const m::room &);
static m::import<prototype> purge thread_local mods::import<prototype> purge
{ {
"m_room", "purge" "m_room", "purge"
}; };
@ -5764,7 +5764,7 @@ console_cmd__room__dagree(opt &out, const string_view &line)
}; };
using prototype = size_t (const m::room &, std::vector<size_t> &); using prototype = size_t (const m::room &, std::vector<size_t> &);
static m::import<prototype> dagree_histogram thread_local mods::import<prototype> dagree_histogram
{ {
"m_room", "dagree_histogram" "m_room", "dagree_histogram"
}; };
@ -5824,7 +5824,7 @@ console_cmd__user__register(opt &out, const string_view &line)
const client *const &, const client *const &,
const bool &); const bool &);
static m::import<prototype> register_user thread_local mods::import<prototype> register_user
{ {
"client_register", "register_user" "client_register", "register_user"
}; };
@ -6385,7 +6385,7 @@ console_cmd__feds__version(opt &out, const string_view &line)
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__version thread_local mods::import<prototype> feds__version
{ {
"federation_federation", "feds__version" "federation_federation", "feds__version"
}; };
@ -6499,7 +6499,7 @@ console_cmd__feds__event(opt &out, const string_view &line)
using prototype = void (const m::event::id &, using prototype = void (const m::event::id &,
std::ostream &); std::ostream &);
static m::import<prototype> feds__event thread_local mods::import<prototype> feds__event
{ {
"federation_federation", "feds__event" "federation_federation", "feds__event"
}; };
@ -6535,7 +6535,7 @@ console_cmd__feds__head(opt &out, const string_view &line)
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__head thread_local mods::import<prototype> feds__head
{ {
"federation_federation", "feds__head" "federation_federation", "feds__head"
}; };
@ -6596,7 +6596,7 @@ console_cmd__feds__auth(opt &out, const string_view &line)
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__head thread_local mods::import<prototype> feds__head
{ {
"federation_federation", "feds__head" "federation_federation", "feds__head"
}; };
@ -6656,7 +6656,7 @@ console_cmd__feds__heads(opt &out, const string_view &line)
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__head thread_local mods::import<prototype> feds__head
{ {
"federation_federation", "feds__head" "federation_federation", "feds__head"
}; };
@ -6743,7 +6743,7 @@ console_cmd__feds__perspective(opt &out, const string_view &line)
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__perspective thread_local mods::import<prototype> feds__perspective
{ {
"federation_federation", "feds__perspective" "federation_federation", "feds__perspective"
}; };
@ -6799,7 +6799,7 @@ console_cmd__feds__backfill(opt &out, const string_view &line)
const size_t &, const size_t &,
std::ostream &); std::ostream &);
static m::import<prototype> feds__backfill thread_local mods::import<prototype> feds__backfill
{ {
"federation_federation", "feds__backfill" "federation_federation", "feds__backfill"
}; };
@ -8067,7 +8067,7 @@ console_cmd__file__room(opt &out, const string_view &line)
const string_view &server, const string_view &server,
const string_view &file); const string_view &file);
static m::import<prototype> file_room_id thread_local mods::import<prototype> file_room_id
{ {
"media_media", "file_room_id" "media_media", "file_room_id"
}; };
@ -8115,7 +8115,7 @@ console_cmd__file__download(opt &out, const string_view &line)
const m::user::id &, const m::user::id &,
const net::hostport &remote); const net::hostport &remote);
static m::import<prototype> download thread_local mods::import<prototype> download
{ {
"media_media", "download" "media_media", "download"
}; };

View file

@ -657,7 +657,7 @@ room_herd(const m::room &room,
const milliseconds &, const milliseconds &,
const std::function<closure_prototype> &); const std::function<closure_prototype> &);
static m::import<prototype> feds__head thread_local mods::import<prototype> feds__head
{ {
"federation_federation", "feds__head" "federation_federation", "feds__head"
}; };

View file

@ -88,7 +88,7 @@ _join_room_hookfn
}; };
using invite_foreign_proto = m::event::id::buf (const m::event &); using invite_foreign_proto = m::event::id::buf (const m::event &);
m::import<invite_foreign_proto> thread_local mods::import<invite_foreign_proto>
invite__foreign invite__foreign
{ {
"client_rooms", "invite__foreign" "client_rooms", "invite__foreign"

View file

@ -71,9 +71,9 @@ noexcept try
}; };
using prototype = int (std::ostream &, const string_view &, const string_view &); using prototype = int (std::ostream &, const string_view &, const string_view &);
const mods::import<prototype> command mods::import<prototype> command
{ {
*console_module, "console_command" console_module, "console_command"s
}; };
std::ostringstream out; std::ostringstream out;

View file

@ -148,7 +148,7 @@ ircd::m::vm::eval__commit_room(eval &eval,
const mutable_buffer &, const mutable_buffer &,
const size_t &, const size_t &,
const bool &); const bool &);
static m::import<prev_prototype> make_prev__buf thread_local mods::import<prev_prototype> make_prev__buf
{ {
"m_room", "make_prev__buf" "m_room", "make_prev__buf"
}; };
@ -181,7 +181,7 @@ ircd::m::vm::eval__commit_room(eval &eval,
const vector_view<const string_view> &, const vector_view<const string_view> &,
const string_view &); const string_view &);
static m::import<auth_prototype> make_auth__buf thread_local mods::import<auth_prototype> make_auth__buf
{ {
"m_room", "make_auth__buf" "m_room", "make_auth__buf"
}; };