mirror of
https://github.com/matrix-construct/construct
synced 2024-10-31 19:08:59 +01:00
207 lines
5 KiB
C++
207 lines
5 KiB
C++
// 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.
|
|
|
|
decltype(ircd::m::vm::log)
|
|
ircd::m::vm::log
|
|
{
|
|
"m.vm", 'v'
|
|
};
|
|
|
|
decltype(ircd::m::vm::dock)
|
|
ircd::m::vm::dock;
|
|
|
|
decltype(ircd::m::vm::ready)
|
|
ircd::m::vm::ready;
|
|
|
|
decltype(ircd::m::vm::default_copts)
|
|
ircd::m::vm::default_copts;
|
|
|
|
decltype(ircd::m::vm::default_opts)
|
|
ircd::m::vm::default_opts;
|
|
|
|
//
|
|
// init
|
|
//
|
|
|
|
ircd::m::vm::init::init()
|
|
{
|
|
id::event::buf event_id;
|
|
sequence::retired = sequence::get(event_id);
|
|
sequence::committed = sequence::retired;
|
|
sequence::uncommitted = sequence::committed;
|
|
|
|
vm::ready = true;
|
|
vm::dock.notify_all();
|
|
|
|
log::info
|
|
{
|
|
log, "BOOT %s @%lu [%s] db:%lu",
|
|
server_name(my()),
|
|
sequence::retired,
|
|
sequence::retired?
|
|
string_view{event_id} : "NO EVENTS"_sv,
|
|
m::dbs::events?
|
|
db::sequence(*m::dbs::events) : 0UL,
|
|
};
|
|
}
|
|
|
|
ircd::m::vm::init::~init()
|
|
noexcept
|
|
{
|
|
vm::ready = false;
|
|
|
|
if(eval::executing || eval::injecting)
|
|
log::warning
|
|
{
|
|
log, "Waiting for exec:%zu inject:%zu pending:%zu evaluations",
|
|
eval::executing,
|
|
eval::injecting,
|
|
sequence::pending,
|
|
};
|
|
|
|
vm::dock.wait([]() noexcept
|
|
{
|
|
return !eval::executing && !eval::injecting;
|
|
});
|
|
|
|
if(sequence::pending)
|
|
log::warning
|
|
{
|
|
log, "Waiting for pending:%zu sequencing (retired:%zu committed:%zu uncommitted:%zu)",
|
|
sequence::pending,
|
|
sequence::retired,
|
|
sequence::committed,
|
|
sequence::uncommitted,
|
|
};
|
|
|
|
sequence::dock.wait([]() noexcept
|
|
{
|
|
return !sequence::pending;
|
|
});
|
|
|
|
event::id::buf event_id;
|
|
const auto retired
|
|
{
|
|
sequence::get(event_id)
|
|
};
|
|
|
|
log::info
|
|
{
|
|
log, "HALT '%s' @%lu [%s] vm:%lu:%lu:%lu db:%lu",
|
|
server_name(my()),
|
|
retired,
|
|
retired?
|
|
string_view{event_id} : "NO EVENTS"_sv,
|
|
sequence::retired,
|
|
sequence::committed,
|
|
sequence::uncommitted,
|
|
m::dbs::events?
|
|
db::sequence(*m::dbs::events) : 0UL,
|
|
};
|
|
|
|
assert(retired == sequence::retired || ircd::read_only);
|
|
}
|
|
|
|
ircd::m::vm::phase
|
|
ircd::m::vm::phase_reflect(const string_view &str)
|
|
noexcept
|
|
{
|
|
phase ret{phase::NONE};
|
|
util::for_each<phase>([&ret, &str]
|
|
(const auto &phase)
|
|
{
|
|
if(reflect(phase) == str)
|
|
{
|
|
ret = phase;
|
|
return false;
|
|
}
|
|
else return true;
|
|
});
|
|
|
|
return ret;
|
|
}
|
|
|
|
ircd::string_view
|
|
ircd::m::vm::reflect(const enum phase &code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case phase::NONE: return "NONE";
|
|
case phase::EXECUTE: return "EXECUTE";
|
|
case phase::CONFORM: return "CONFORM";
|
|
case phase::DUPWAIT: return "DUPWAIT";
|
|
case phase::DUPCHK: return "DUPCHK";
|
|
case phase::ISSUE: return "ISSUE";
|
|
case phase::ACCESS: return "ACCESS";
|
|
case phase::EMPTION: return "EMPTION";
|
|
case phase::VERIFY: return "VERIFY";
|
|
case phase::FETCH_AUTH: return "FETCH_AUTH";
|
|
case phase::AUTH_STATIC: return "AUTH_STATIC";
|
|
case phase::FETCH_PREV: return "FETCH_PREV";
|
|
case phase::FETCH_STATE: return "FETCH_STATE";
|
|
case phase::PRECOMMIT: return "PRECOMMIT";
|
|
case phase::PREINDEX: return "PREINDEX";
|
|
case phase::AUTH_RELA: return "AUTH_RELA";
|
|
case phase::COMMIT: return "COMMIT";
|
|
case phase::AUTH_PRES: return "AUTH_PRES";
|
|
case phase::EVALUATE: return "EVALUATE";
|
|
case phase::INDEX: return "INDEX";
|
|
case phase::POST: return "POST";
|
|
case phase::WRITE: return "WRITE";
|
|
case phase::RETIRE: return "RETIRE";
|
|
case phase::NOTIFY: return "NOTIFY";
|
|
case phase::EFFECTS: return "EFFECTS";
|
|
case phase::_NUM_: break;
|
|
}
|
|
|
|
return "??????";
|
|
}
|
|
|
|
ircd::http::code
|
|
ircd::m::vm::http_code(const fault &code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case fault::ACCEPT: return http::OK;
|
|
case fault::EXISTS: return http::CONFLICT;
|
|
case fault::INVALID: return http::BAD_REQUEST;
|
|
case fault::GENERAL: return http::UNAUTHORIZED;
|
|
case fault::AUTH: return http::FORBIDDEN;
|
|
case fault::STATE: return http::NOT_FOUND;
|
|
case fault::EVENT: return http::NOT_FOUND;
|
|
case fault::BOUNCE: break;
|
|
case fault::DONOTWANT: break;
|
|
case fault::DENIED: return http::FORBIDDEN;
|
|
case fault::IDENT: return http::UNAUTHORIZED;
|
|
}
|
|
|
|
return http::INTERNAL_SERVER_ERROR;
|
|
}
|
|
|
|
ircd::string_view
|
|
ircd::m::vm::reflect(const enum fault &code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case fault::ACCEPT: return "#ACCEPT";
|
|
case fault::EXISTS: return "#EXISTS";
|
|
case fault::GENERAL: return "#GENERAL";
|
|
case fault::INVALID: return "#INVALID";
|
|
case fault::AUTH: return "#AUTH";
|
|
case fault::EVENT: return "#EVENT";
|
|
case fault::STATE: return "#STATE";
|
|
case fault::BOUNCE: return "#BOUNCE";
|
|
case fault::DONOTWANT: return "#DONOTWANT";
|
|
case fault::DENIED: return "#DENIED";
|
|
case fault::IDENT: return "#IDENT";
|
|
}
|
|
|
|
return "??????";
|
|
}
|