mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd:Ⓜ️ Reinterface append(event) into event::append; move to module. (#109)
This commit is contained in:
parent
7c5ef32008
commit
d8fcbf7325
14 changed files with 261 additions and 213 deletions
|
@ -1,29 +0,0 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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_APPEND
|
||||
|
||||
namespace ircd::m
|
||||
{
|
||||
struct event_append_opts
|
||||
{
|
||||
const event::idx *event_idx {nullptr};
|
||||
const string_view *client_txnid {nullptr};
|
||||
const id::user *user_id {nullptr};
|
||||
const room *user_room {nullptr};
|
||||
const int64_t *room_depth {nullptr};
|
||||
long age {std::numeric_limits<long>::min()};
|
||||
bool query_txnid {true};
|
||||
};
|
||||
|
||||
bool append(json::stack::object &, const event &, const event_append_opts & = {});
|
||||
bool append(json::stack::array &, const event &, const event_append_opts & = {});
|
||||
}
|
46
include/ircd/m/event/append.h
Normal file
46
include/ircd/m/event/append.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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_EVENT_APPEND
|
||||
|
||||
struct ircd::m::event::append
|
||||
:boolean
|
||||
{
|
||||
struct opts;
|
||||
|
||||
append(json::stack::object &, const event &, const opts &);
|
||||
append(json::stack::object &, const event &);
|
||||
append(json::stack::array &, const event &, const opts &);
|
||||
append(json::stack::array &, const event &);
|
||||
};
|
||||
|
||||
struct ircd::m::event::append::opts
|
||||
{
|
||||
const event::idx *event_idx {nullptr};
|
||||
const string_view *client_txnid {nullptr};
|
||||
const id::user *user_id {nullptr};
|
||||
const room *user_room {nullptr};
|
||||
const int64_t *room_depth {nullptr};
|
||||
long age {std::numeric_limits<long>::min()};
|
||||
bool query_txnid {true};
|
||||
};
|
||||
|
||||
inline
|
||||
ircd::m::event::append::append(json::stack::array &a,
|
||||
const event &e)
|
||||
:append{a, e, {}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::m::event::append::append(json::stack::object &o,
|
||||
const event &e)
|
||||
:append{o, e, {}}
|
||||
{}
|
|
@ -101,6 +101,7 @@ struct ircd::m::event
|
|||
struct auth;
|
||||
struct fetch;
|
||||
struct conforms;
|
||||
struct append;
|
||||
|
||||
using keys = json::keys<event>;
|
||||
using id = m::id::event;
|
||||
|
@ -169,6 +170,7 @@ struct ircd::m::event
|
|||
#include "prefetch.h"
|
||||
#include "conforms.h"
|
||||
#include "pretty.h"
|
||||
#include "append.h"
|
||||
|
||||
inline ircd::m::event::operator
|
||||
const id &()
|
||||
|
|
|
@ -79,7 +79,6 @@ namespace ircd::m
|
|||
#include "sync.h"
|
||||
#include "fetch.h"
|
||||
#include "breadcrumb_rooms.h"
|
||||
#include "append.h"
|
||||
|
||||
struct ircd::m::init
|
||||
{
|
||||
|
|
|
@ -231,6 +231,7 @@ ircd::m::module_names
|
|||
"m_direct_to_device",
|
||||
"m_breadcrumb_rooms",
|
||||
"m_ignored_user_list",
|
||||
"m_event_append",
|
||||
"key_query",
|
||||
"key_server",
|
||||
"identity_pubkey",
|
||||
|
|
166
ircd/m_event.cc
166
ircd/m_event.cc
|
@ -364,172 +364,6 @@ ircd::m::pretty_oneline(std::ostream &s,
|
|||
return s;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/append.h
|
||||
//
|
||||
|
||||
bool
|
||||
ircd::m::append(json::stack::array &array,
|
||||
const event &event_,
|
||||
const event_append_opts &opts)
|
||||
{
|
||||
json::stack::object object
|
||||
{
|
||||
array
|
||||
};
|
||||
|
||||
return append(object, event_, opts);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::append(json::stack::object &object,
|
||||
const event &event,
|
||||
const event_append_opts &opts)
|
||||
{
|
||||
const bool has_event_idx
|
||||
{
|
||||
opts.event_idx && *opts.event_idx
|
||||
};
|
||||
|
||||
const bool has_client_txnid
|
||||
{
|
||||
opts.client_txnid && *opts.client_txnid
|
||||
};
|
||||
|
||||
const bool has_user
|
||||
{
|
||||
opts.user_id && opts.user_room
|
||||
};
|
||||
|
||||
const bool sender_is_user
|
||||
{
|
||||
has_user && json::get<"sender"_>(event) == *opts.user_id
|
||||
};
|
||||
|
||||
const auto txnid_idx
|
||||
{
|
||||
!has_client_txnid && sender_is_user && opts.query_txnid?
|
||||
opts.user_room->get(std::nothrow, "ircd.client.txnid", event.event_id):
|
||||
0UL
|
||||
};
|
||||
|
||||
#if defined(RB_DEBUG) && 0
|
||||
if(!has_client_txnid && !txnid_idx && sender_is_user && opts.query_txnid)
|
||||
log::dwarning
|
||||
{
|
||||
log, "Could not find transaction_id for %s from %s in %s",
|
||||
string_view{event.event_id},
|
||||
json::get<"sender"_>(event),
|
||||
json::get<"room_id"_>(event)
|
||||
};
|
||||
#endif
|
||||
|
||||
if(has_event_idx && !defined(json::get<"state_key"_>(event)) && m::redacted(*opts.event_idx))
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
log, "Not sending event '%s' because redacted.",
|
||||
string_view{event.event_id},
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!json::get<"state_key"_>(event) && has_user)
|
||||
{
|
||||
const m::user::ignores ignores{*opts.user_id};
|
||||
if(ignores.enforce("events") && ignores.has(json::get<"sender"_>(event)))
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
log, "Not sending event '%s' because '%s' is ignored by '%s'",
|
||||
string_view{event.event_id},
|
||||
json::get<"sender"_>(event),
|
||||
string_view{*opts.user_id}
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!json::get<"event_id"_>(event))
|
||||
{
|
||||
auto _event(event);
|
||||
json::get<"event_id"_>(_event) = event.event_id;
|
||||
object.append(_event);
|
||||
}
|
||||
else object.append(event);
|
||||
|
||||
if(json::get<"state_key"_>(event) && has_event_idx)
|
||||
{
|
||||
const auto prev_idx
|
||||
{
|
||||
room::state::prev(*opts.event_idx)
|
||||
};
|
||||
|
||||
if(prev_idx)
|
||||
m::get(std::nothrow, prev_idx, "content", [&object]
|
||||
(const json::object &content)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
object, "prev_content", content
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
json::stack::object unsigned_
|
||||
{
|
||||
object, "unsigned"
|
||||
};
|
||||
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "age", json::value
|
||||
{
|
||||
// When the opts give an explicit age, use it.
|
||||
opts.age != std::numeric_limits<long>::min()?
|
||||
opts.age:
|
||||
|
||||
// If we have depth information, craft a value based on the
|
||||
// distance to the head depth; if this is 0 in riot the event will
|
||||
// "stick" at the bottom of the timeline. This may be advantageous
|
||||
// in the future but for now we make sure the result is non-zero.
|
||||
json::get<"depth"_>(event) >= 0 && opts.room_depth && *opts.room_depth >= 0L?
|
||||
(*opts.room_depth + 1 - json::get<"depth"_>(event)) + 1:
|
||||
|
||||
// We don't have depth information, so we use the origin_server_ts.
|
||||
// It is bad if it conflicts with other appends in the room which
|
||||
// did have depth information.
|
||||
!opts.room_depth && json::get<"origin_server_ts"_>(event)?
|
||||
ircd::time<milliseconds>() - json::get<"origin_server_ts"_>(event):
|
||||
|
||||
// Finally, this special value will eliminate the age altogether
|
||||
// during serialization.
|
||||
json::undefined_number
|
||||
}
|
||||
};
|
||||
|
||||
if(has_client_txnid)
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "transaction_id", *opts.client_txnid
|
||||
};
|
||||
|
||||
if(txnid_idx)
|
||||
m::get(std::nothrow, txnid_idx, "content", [&unsigned_]
|
||||
(const json::object &content)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "transaction_id", unquote(content.get("transaction_id"))
|
||||
};
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// event/conforms.h
|
||||
|
|
|
@ -100,6 +100,7 @@ m_moduledir = @moduledir@
|
|||
|
||||
m_vm_la_SOURCES = m_vm.cc
|
||||
m_noop_la_SOURCES = m_noop.cc
|
||||
m_event_append_la_SOURCES = m_event_append.cc
|
||||
m_user_la_SOURCES = m_user.cc
|
||||
m_user_events_la_SOURCES = m_user_events.cc
|
||||
m_user_rooms_la_SOURCES = m_user_rooms.cc
|
||||
|
@ -141,6 +142,7 @@ m_listen_la_SOURCES = m_listen.cc
|
|||
m_module_LTLIBRARIES = \
|
||||
m_vm.la \
|
||||
m_noop.la \
|
||||
m_event_append.la \
|
||||
m_user.la \
|
||||
m_user_events.la \
|
||||
m_user_rooms.la \
|
||||
|
|
|
@ -369,10 +369,13 @@ append_event(json::stack::array &out,
|
|||
const int64_t &room_depth,
|
||||
const m::user::room &user_room)
|
||||
{
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.room_depth = &room_depth;
|
||||
opts.user_room = &user_room;
|
||||
opts.user_id = &user_room.user.user_id;
|
||||
return m::append(out, event, opts);
|
||||
return m::event::append
|
||||
{
|
||||
out, event, opts
|
||||
};
|
||||
}
|
||||
|
|
|
@ -153,13 +153,13 @@ get__context(client &client,
|
|||
ret, "event"
|
||||
};
|
||||
|
||||
// We use m::append() to modify/add/remove data for this client.
|
||||
m::event_append_opts opts;
|
||||
// We use m::event::append() to modify/add/remove data for this client.
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event.event_idx;
|
||||
opts.user_id = &user_room.user.user_id;
|
||||
opts.user_room = &user_room;
|
||||
opts.room_depth = &room_depth;
|
||||
m::append(_event, event, opts);
|
||||
m::event::append(_event, event, opts);
|
||||
}
|
||||
|
||||
// Counters for debug messages
|
||||
|
@ -320,10 +320,10 @@ _append(json::stack::array &chunk,
|
|||
const int64_t &room_depth,
|
||||
const bool &query_txnid)
|
||||
{
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.user_id = &user_room.user.user_id;
|
||||
opts.user_room = &user_room;
|
||||
opts.room_depth = &room_depth;
|
||||
return m::append(chunk, event, opts);
|
||||
return m::event::append(chunk, event, opts);
|
||||
}
|
||||
|
|
|
@ -203,13 +203,13 @@ get__initialsync_local(client &client,
|
|||
if(!event.valid)
|
||||
return true;
|
||||
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event.event_idx;
|
||||
opts.user_id = &user.user_id;
|
||||
opts.user_room = &user_room;
|
||||
opts.room_depth = &room_depth;
|
||||
opts.query_txnid = false;
|
||||
m::append(state, event, opts);
|
||||
m::event::append(state, event, opts);
|
||||
return true;
|
||||
}});
|
||||
state.~array();
|
||||
|
@ -248,13 +248,13 @@ get__initialsync_local(client &client,
|
|||
const m::event &event(*it);
|
||||
const auto &event_idx(it.event_idx());
|
||||
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.user_id = &user.user_id;
|
||||
opts.user_room = &user_room;
|
||||
opts.room_depth = &room_depth;
|
||||
opts.query_txnid = true;
|
||||
m::append(chunk, event, opts);
|
||||
m::event::append(chunk, event, opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -212,12 +212,12 @@ _append(json::stack::array &chunk,
|
|||
const m::user::room &user_room,
|
||||
const int64_t &room_depth)
|
||||
{
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.user_id = &user_room.user.user_id;
|
||||
opts.user_room = &user_room;
|
||||
opts.room_depth = &room_depth;
|
||||
return m::append(chunk, event, opts);
|
||||
return m::event::append(chunk, event, opts);
|
||||
}
|
||||
|
||||
// Client-Server 6.3.6 query parameters
|
||||
|
|
|
@ -382,11 +382,11 @@ ircd::m::sync::room_state_append(data &data,
|
|||
const m::event &event,
|
||||
const m::event::idx &event_idx)
|
||||
{
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.user_id = &data.user.user_id;
|
||||
opts.user_room = &data.user_room;
|
||||
opts.query_txnid = false;
|
||||
opts.room_depth = &data.room_depth;
|
||||
return m::append(events, event, opts);
|
||||
return m::event::append(events, event, opts);
|
||||
}
|
||||
|
|
|
@ -305,11 +305,11 @@ ircd::m::sync::_room_timeline_append(data &data,
|
|||
const m::event::idx &event_idx,
|
||||
const m::event &event)
|
||||
{
|
||||
m::event_append_opts opts;
|
||||
m::event::append::opts opts;
|
||||
opts.event_idx = &event_idx;
|
||||
opts.client_txnid = &data.client_txnid;
|
||||
opts.user_id = &data.user.user_id;
|
||||
opts.user_room = &data.user_room;
|
||||
opts.room_depth = &data.room_depth;
|
||||
return m::append(events, event, opts);
|
||||
return m::event::append(events, event, opts);
|
||||
}
|
||||
|
|
190
modules/m_event_append.cc
Normal file
190
modules/m_event_append.cc
Normal file
|
@ -0,0 +1,190 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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
|
||||
{
|
||||
"Matrix Event Library :Streaming tools"
|
||||
};
|
||||
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::event::append::append(json::stack::array &array,
|
||||
const event &event_,
|
||||
const opts &opts)
|
||||
:boolean{[&]
|
||||
{
|
||||
json::stack::object object
|
||||
{
|
||||
array
|
||||
};
|
||||
|
||||
const bool ret
|
||||
{
|
||||
append
|
||||
{
|
||||
object, event_, opts
|
||||
}
|
||||
};
|
||||
|
||||
return ret;
|
||||
}}
|
||||
{
|
||||
}
|
||||
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::event::append::append(json::stack::object &object,
|
||||
const event &event,
|
||||
const opts &opts)
|
||||
:boolean{[&]
|
||||
{
|
||||
const bool has_event_idx
|
||||
{
|
||||
opts.event_idx && *opts.event_idx
|
||||
};
|
||||
|
||||
const bool has_client_txnid
|
||||
{
|
||||
opts.client_txnid && *opts.client_txnid
|
||||
};
|
||||
|
||||
const bool has_user
|
||||
{
|
||||
opts.user_id && opts.user_room
|
||||
};
|
||||
|
||||
const bool sender_is_user
|
||||
{
|
||||
has_user && json::get<"sender"_>(event) == *opts.user_id
|
||||
};
|
||||
|
||||
const auto txnid_idx
|
||||
{
|
||||
!has_client_txnid && sender_is_user && opts.query_txnid?
|
||||
opts.user_room->get(std::nothrow, "ircd.client.txnid", event.event_id):
|
||||
0UL
|
||||
};
|
||||
|
||||
#if defined(RB_DEBUG) && 0
|
||||
if(!has_client_txnid && !txnid_idx && sender_is_user && opts.query_txnid)
|
||||
log::dwarning
|
||||
{
|
||||
log, "Could not find transaction_id for %s from %s in %s",
|
||||
string_view{event.event_id},
|
||||
json::get<"sender"_>(event),
|
||||
json::get<"room_id"_>(event)
|
||||
};
|
||||
#endif
|
||||
|
||||
if(has_event_idx && !defined(json::get<"state_key"_>(event)) && m::redacted(*opts.event_idx))
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
log, "Not sending event '%s' because redacted.",
|
||||
string_view{event.event_id},
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!json::get<"state_key"_>(event) && has_user)
|
||||
{
|
||||
const m::user::ignores ignores{*opts.user_id};
|
||||
if(ignores.enforce("events") && ignores.has(json::get<"sender"_>(event)))
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
log, "Not sending event '%s' because '%s' is ignored by '%s'",
|
||||
string_view{event.event_id},
|
||||
json::get<"sender"_>(event),
|
||||
string_view{*opts.user_id}
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!json::get<"event_id"_>(event))
|
||||
{
|
||||
auto _event(event);
|
||||
json::get<"event_id"_>(_event) = event.event_id;
|
||||
object.append(_event);
|
||||
}
|
||||
else object.append(event);
|
||||
|
||||
if(json::get<"state_key"_>(event) && has_event_idx)
|
||||
{
|
||||
const auto prev_idx
|
||||
{
|
||||
room::state::prev(*opts.event_idx)
|
||||
};
|
||||
|
||||
if(prev_idx)
|
||||
m::get(std::nothrow, prev_idx, "content", [&object]
|
||||
(const json::object &content)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
object, "prev_content", content
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
json::stack::object unsigned_
|
||||
{
|
||||
object, "unsigned"
|
||||
};
|
||||
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "age", json::value
|
||||
{
|
||||
// When the opts give an explicit age, use it.
|
||||
opts.age != std::numeric_limits<long>::min()?
|
||||
opts.age:
|
||||
|
||||
// If we have depth information, craft a value based on the
|
||||
// distance to the head depth; if this is 0 in riot the event will
|
||||
// "stick" at the bottom of the timeline. This may be advantageous
|
||||
// in the future but for now we make sure the result is non-zero.
|
||||
json::get<"depth"_>(event) >= 0 && opts.room_depth && *opts.room_depth >= 0L?
|
||||
(*opts.room_depth + 1 - json::get<"depth"_>(event)) + 1:
|
||||
|
||||
// We don't have depth information, so we use the origin_server_ts.
|
||||
// It is bad if it conflicts with other appends in the room which
|
||||
// did have depth information.
|
||||
!opts.room_depth && json::get<"origin_server_ts"_>(event)?
|
||||
ircd::time<milliseconds>() - json::get<"origin_server_ts"_>(event):
|
||||
|
||||
// Finally, this special value will eliminate the age altogether
|
||||
// during serialization.
|
||||
json::undefined_number
|
||||
}
|
||||
};
|
||||
|
||||
if(has_client_txnid)
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "transaction_id", *opts.client_txnid
|
||||
};
|
||||
|
||||
if(txnid_idx)
|
||||
m::get(std::nothrow, txnid_idx, "content", [&unsigned_]
|
||||
(const json::object &content)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
unsigned_, "transaction_id", unquote(content.get("transaction_id"))
|
||||
};
|
||||
});
|
||||
|
||||
return true;
|
||||
}}
|
||||
{
|
||||
}
|
Loading…
Reference in a new issue