0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 10:08:56 +02:00

ircd:Ⓜ️:presence: Improve get() interface based on realistic usage needs.

This commit is contained in:
Jason Volk 2019-01-26 15:24:29 -08:00
parent fc162b41b3
commit c080d5523c
4 changed files with 132 additions and 65 deletions

View file

@ -34,18 +34,20 @@ struct ircd::m::presence
:edu::m_presence
{
using closure = std::function<void (const json::object &)>;
using event_closure = std::function<void (const m::event &, const json::object &)>;
using closure_event = std::function<void (const m::event &)>;
static bool valid_state(const string_view &state);
static void get(const user &, const event_closure &);
static void get(const user &, const closure &);
static bool get(std::nothrow_t, const user &, const event_closure &);
static event::idx get(std::nothrow_t, const user &);
static event::idx get(const user &);
static bool get(std::nothrow_t, const user &, const closure_event &, const event::fetch::opts *const & = nullptr);
static bool get(std::nothrow_t, const user &, const closure &);
static json::object get(const user &, const mutable_buffer &);
static void get(const user &, const closure &);
static event::id::buf set(const presence &);
static event::id::buf set(const user &, const string_view &, const string_view &status = {});
presence(const user &, const mutable_buffer &);
using edu::m_presence::m_presence;
presence(const user &, const mutable_buffer &);
};

102
ircd/m.cc
View file

@ -1307,10 +1307,20 @@ ircd::m::typing::for_each(const closure_bool &closure)
ircd::m::presence::presence(const user &user,
const mutable_buffer &buf)
:presence
:edu::m_presence{[&user, &buf]
{
get(user, buf)
}
json::object ret;
get(user, [&ret, &buf]
(const json::object &content)
{
ret =
{
data(buf), copy(buf, string_view{content})
};
});
return ret;
}()}
{
}
@ -1340,40 +1350,14 @@ ircd::m::presence::set(const presence &object)
return function(object);
}
ircd::json::object
ircd::m::presence::get(const user &user,
const mutable_buffer &buffer)
{
json::object ret;
get(std::nothrow, user, [&ret, &buffer]
(const json::object &object)
{
ret = { data(buffer), copy(buffer, object) };
});
return ret;
}
void
ircd::m::presence::get(const user &user,
const closure &closure)
{
get(user, [&closure]
(const m::event &event, const json::object &content)
{
closure(content);
});
}
void
ircd::m::presence::get(const user &user,
const event_closure &closure)
{
if(!get(std::nothrow, user, closure))
throw m::NOT_FOUND
{
"No presence found for %s",
string_view{user.user_id}
"No presence found for %s", string_view{user.user_id}
};
}
@ -1382,26 +1366,70 @@ ircd::m::presence::get(std::nothrow_t,
const user &user,
const closure &closure)
{
return get(std::nothrow, user, [&closure]
(const m::event &event, const json::object &content)
static const m::event::fetch::opts fopts
{
closure(content);
});
m::event::keys::include {"content"}
};
const auto reclosure{[&closure]
(const m::event &event)
{
closure(json::get<"content"_>(event));
}};
return get(std::nothrow, user, reclosure, &fopts);
}
bool
ircd::m::presence::get(std::nothrow_t,
const user &user,
const event_closure &closure)
const closure_event &closure,
const event::fetch::opts *const &opts)
{
using prototype = bool (std::nothrow_t, const m::user &, const event_closure &);
using prototype = bool (std::nothrow_t, const m::user &, const closure_event &, const event::fetch::opts &);
static mods::import<prototype> function
{
"m_presence", "get__m_presence"
};
return function(std::nothrow, user, closure);
const event::fetch::opts &fopts
{
opts? *opts : event::fetch::default_opts
};
return function(std::nothrow, user, closure, fopts);
}
ircd::m::event::idx
ircd::m::presence::get(const user &user)
{
const event::idx ret
{
get(std::nothrow, user)
};
if(!ret)
throw m::NOT_FOUND
{
"No presence found for %s", string_view{user.user_id}
};
return ret;
}
ircd::m::event::idx
ircd::m::presence::get(std::nothrow_t,
const user &user)
{
using prototype = event::idx (std::nothrow_t, const m::user &);
static mods::import<prototype> function
{
"m_presence", "get__m_presence__event_idx"
};
return function(std::nothrow, user);
}
bool

View file

@ -134,9 +134,13 @@ ircd::m::sync::presence_polylog_events(data &data)
m::sync::pool, q, [&data, &append_event]
(const m::user::id user_id)
{
//TODO: check something better than user_room head?
if(head_idx(std::nothrow, user::room(user_id)) >= data.range.first)
m::presence::get(std::nothrow, user_id, append_event);
const event::idx event_idx
{
m::presence::get(std::nothrow, user_id)
};
if(apropos(data, event_idx))
m::get(std::nothrow, event_idx, "content", append_event);
}
};

View file

@ -100,9 +100,14 @@ try
}
bool useful{true};
m::presence::get(std::nothrow, user_id, [&event, &object, &useful]
(const m::event &existing_event, const json::object &existing_object)
const auto closure{[&event, &object, &useful]
(const m::event &existing_event)
{
const json::object &existing_object
{
json::get<"content"_>(existing_event)
};
// This check shouldn't have to exist. I think this was a result of corrupting
// my DB during development and it fails on only one user. Nevertheless, it's
// a valid assertion so might as well keep it.
@ -146,8 +151,14 @@ try
useful = true;
else
useful = false;
});
}};
static const m::event::fetch::opts fopts
{
m::event::keys::include {"content", "origin_server_ts"}
};
m::presence::get(std::nothrow, user_id, closure, &fopts);
if(!useful)
return;
@ -177,31 +188,53 @@ catch(const m::error &e)
};
}
extern "C" m::event::idx
get__m_presence__event_idx(const std::nothrow_t,
const m::user &user)
{
const m::user::room user_room
{
user
};
const m::room::state state
{
user_room
};
m::event::idx ret{0};
state.get(std::nothrow, "ircd.presence", "", [&ret]
(const m::event::idx &event_idx)
{
ret = event_idx;
});
return ret;
}
extern "C" bool
get__m_presence(const std::nothrow_t,
const m::user &user,
const m::presence::event_closure &closure)
const m::presence::closure_event &closure,
const m::event::fetch::opts &fopts)
{
static const m::event::fetch::opts fopts
const m::event::idx event_idx
{
m::event::keys::include
{
"event_id",
"content",
"origin_server_ts",
}
get__m_presence__event_idx(std::nothrow, user)
};
const m::user::room user_room
if(!event_idx)
return false;
const m::event::fetch event
{
user, nullptr, &fopts
event_idx, std::nothrow, fopts
};
return user_room.get(std::nothrow, "ircd.presence", "", [&closure]
(const m::event &event)
{
closure(event, json::get<"content"_>(event));
});
if(event.valid)
closure(event);
return event.valid;
}
extern "C" m::event::id::buf