2019-01-04 02:21:02 +01:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
ircd::mapi::header
|
|
|
|
IRCD_MODULE
|
|
|
|
{
|
|
|
|
"Client Sync :Presence"
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace ircd::m::sync
|
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
static void presence_events_polylog(data &);
|
2019-01-04 02:21:02 +01:00
|
|
|
static bool presence_polylog(data &);
|
2019-01-04 23:47:01 +01:00
|
|
|
static bool presence_linear(data &);
|
2019-01-04 02:21:02 +01:00
|
|
|
extern item presence;
|
|
|
|
}
|
|
|
|
|
|
|
|
decltype(ircd::m::sync::presence)
|
|
|
|
ircd::m::sync::presence
|
|
|
|
{
|
|
|
|
"presence",
|
2019-01-04 23:47:01 +01:00
|
|
|
presence_polylog,
|
|
|
|
presence_linear,
|
2019-01-04 02:21:02 +01:00
|
|
|
};
|
|
|
|
|
2019-01-04 23:47:01 +01:00
|
|
|
bool
|
|
|
|
ircd::m::sync::presence_linear(data &data)
|
2019-01-04 02:21:02 +01:00
|
|
|
{
|
2019-01-04 23:47:01 +01:00
|
|
|
if(!data.event)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(json::get<"type"_>(*data.event) != "ircd.presence")
|
|
|
|
return false;
|
|
|
|
|
|
|
|
json::stack::object object
|
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
data.out
|
2019-01-04 23:47:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// sender
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "sender", unquote(at<"content"_>(*data.event).get("user_id"))
|
|
|
|
};
|
|
|
|
|
|
|
|
// type
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "type", json::value{"m.presence"}
|
|
|
|
};
|
|
|
|
|
|
|
|
// content
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "content", at<"content"_>(*data.event)
|
|
|
|
};
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-04 02:21:02 +01:00
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::sync::presence_polylog(data &data)
|
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
json::stack::object object
|
|
|
|
{
|
|
|
|
data.out
|
|
|
|
};
|
|
|
|
|
|
|
|
presence_events_polylog(data);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ircd::m::sync::presence_events_polylog(data &data)
|
|
|
|
{
|
|
|
|
json::stack::array array
|
2019-01-04 02:21:02 +01:00
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
data.out, "events"
|
2019-01-04 02:21:02 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
ctx::mutex mutex;
|
|
|
|
const auto closure{[&data, &array, &mutex]
|
|
|
|
(const json::object &event)
|
|
|
|
{
|
|
|
|
// Lock the json::stack for the append operations. This mutex will only be
|
|
|
|
// contended during a json::stack flush to the client; not during database
|
|
|
|
// queries leading to this.
|
|
|
|
const std::lock_guard<decltype(mutex)> l{mutex};
|
2019-01-09 00:10:06 +01:00
|
|
|
json::stack::object object
|
|
|
|
{
|
|
|
|
array
|
|
|
|
};
|
2019-01-04 02:21:02 +01:00
|
|
|
|
|
|
|
// sender
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "sender", unquote(event.get("user_id"))
|
|
|
|
};
|
|
|
|
|
|
|
|
// type
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "type", json::value{"m.presence"}
|
|
|
|
};
|
|
|
|
|
|
|
|
// content
|
|
|
|
json::stack::member
|
|
|
|
{
|
|
|
|
object, "content", event
|
|
|
|
};
|
|
|
|
}};
|
|
|
|
|
|
|
|
//TODO: conf
|
2019-01-09 00:10:06 +01:00
|
|
|
static const size_t fibers(16);
|
|
|
|
std::array<string_view, fibers> q;
|
|
|
|
std::array<char[256], fibers> buf;
|
2019-01-04 02:21:02 +01:00
|
|
|
ctx::parallel<string_view> parallel
|
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
m::sync::pool, q, [&data, &closure](const auto &user_id)
|
|
|
|
{
|
|
|
|
const m::user user{user_id};
|
|
|
|
const m::user::room user_room{user};
|
|
|
|
//TODO: can't check event_idx cuz only closed presence content
|
|
|
|
if(head_idx(std::nothrow, user_room) > data.since)
|
|
|
|
m::presence::get(std::nothrow, user, closure);
|
|
|
|
}
|
2019-01-04 02:21:02 +01:00
|
|
|
};
|
|
|
|
|
2019-01-09 00:10:06 +01:00
|
|
|
const m::user::mitsein mitsein{data.user};
|
|
|
|
mitsein.for_each("join", [¶llel, &q, &buf]
|
|
|
|
(const m::user &user)
|
2019-01-04 02:21:02 +01:00
|
|
|
{
|
2019-01-09 00:10:06 +01:00
|
|
|
q[parallel.snd] = strlcpy(buf[parallel.snd], user.user_id);
|
2019-01-04 02:21:02 +01:00
|
|
|
parallel();
|
2019-01-09 00:10:06 +01:00
|
|
|
});
|
2019-01-04 02:21:02 +01:00
|
|
|
}
|