mirror of
https://github.com/matrix-construct/construct
synced 2024-11-30 02:32:43 +01:00
modules/client/sync: Move the sync::args ctor definition into unit.
This commit is contained in:
parent
8e5e599690
commit
6495fa55d5
2 changed files with 122 additions and 114 deletions
|
@ -119,31 +119,6 @@ ircd::m::sync::longpoll_enable
|
||||||
{ "default", true },
|
{ "default", true },
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// sync/args.h
|
|
||||||
//
|
|
||||||
|
|
||||||
ircd::conf::item<ircd::milliseconds>
|
|
||||||
ircd::m::sync::args::timeout_max
|
|
||||||
{
|
|
||||||
{ "name", "ircd.client.sync.timeout.max" },
|
|
||||||
{ "default", 180 * 1000L },
|
|
||||||
};
|
|
||||||
|
|
||||||
ircd::conf::item<ircd::milliseconds>
|
|
||||||
ircd::m::sync::args::timeout_min
|
|
||||||
{
|
|
||||||
{ "name", "ircd.client.sync.timeout.min" },
|
|
||||||
{ "default", 15 * 1000L },
|
|
||||||
};
|
|
||||||
|
|
||||||
ircd::conf::item<ircd::milliseconds>
|
|
||||||
ircd::m::sync::args::timeout_default
|
|
||||||
{
|
|
||||||
{ "name", "ircd.client.sync.timeout.default" },
|
|
||||||
{ "default", 90 * 1000L },
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// GET sync
|
// GET sync
|
||||||
//
|
//
|
||||||
|
@ -1026,22 +1001,90 @@ noexcept
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// sync/args.h
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::conf::item<ircd::milliseconds>
|
||||||
|
ircd::m::sync::args::timeout_max
|
||||||
|
{
|
||||||
|
{ "name", "ircd.client.sync.timeout.max" },
|
||||||
|
{ "default", 180 * 1000L },
|
||||||
|
};
|
||||||
|
|
||||||
|
ircd::conf::item<ircd::milliseconds>
|
||||||
|
ircd::m::sync::args::timeout_min
|
||||||
|
{
|
||||||
|
{ "name", "ircd.client.sync.timeout.min" },
|
||||||
|
{ "default", 15 * 1000L },
|
||||||
|
};
|
||||||
|
|
||||||
|
ircd::conf::item<ircd::milliseconds>
|
||||||
|
ircd::m::sync::args::timeout_default
|
||||||
|
{
|
||||||
|
{ "name", "ircd.client.sync.timeout.default" },
|
||||||
|
{ "default", 90 * 1000L },
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// args::args
|
// args::args
|
||||||
//
|
//
|
||||||
|
|
||||||
ircd::m::sync::args::args(const resource::request &request)
|
ircd::m::sync::args::args(const resource::request &request)
|
||||||
try
|
try
|
||||||
:request
|
:filter_id
|
||||||
{
|
{
|
||||||
request
|
request.query["filter"]
|
||||||
|
}
|
||||||
|
,since_token
|
||||||
|
{
|
||||||
|
split(request.query.get("since", "0"_sv), '_')
|
||||||
|
}
|
||||||
|
,since
|
||||||
|
{
|
||||||
|
lex_cast<uint64_t>(since_token.first)
|
||||||
|
}
|
||||||
|
,next_batch_token
|
||||||
|
{
|
||||||
|
request.query.get("next_batch", since_token.second)
|
||||||
|
}
|
||||||
|
,next_batch
|
||||||
|
{
|
||||||
|
uint64_t(lex_cast<int64_t>(next_batch_token?: "-1"_sv))
|
||||||
|
}
|
||||||
|
,timesout{[&request]
|
||||||
|
{
|
||||||
|
auto ret
|
||||||
|
{
|
||||||
|
request.query.get("timeout", milliseconds(timeout_default))
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = std::min(ret, milliseconds(timeout_max));
|
||||||
|
ret = std::max(ret, milliseconds(timeout_min));
|
||||||
|
return now<steady_point>() + ret;
|
||||||
|
}()}
|
||||||
|
,full_state
|
||||||
|
{
|
||||||
|
request.query.get("full_state", false)
|
||||||
|
}
|
||||||
|
,set_presence
|
||||||
|
{
|
||||||
|
request.query.get("set_presence", true)
|
||||||
|
}
|
||||||
|
,phased
|
||||||
|
{
|
||||||
|
request.query.get("phased", true)
|
||||||
|
}
|
||||||
|
,semaphore
|
||||||
|
{
|
||||||
|
request.query.get("semaphore", false)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
catch(const bad_lex_cast &e)
|
catch(const bad_lex_cast &e)
|
||||||
{
|
{
|
||||||
throw m::BAD_REQUEST
|
throw m::BAD_REQUEST
|
||||||
{
|
{
|
||||||
"Since parameter invalid :%s", e.what()
|
"Since parameter invalid :%s", e.what()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,111 +8,76 @@
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
// full license for this software is available in the LICENSE file.
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
namespace ircd::m::sync
|
||||||
|
{
|
||||||
|
struct args;
|
||||||
|
}
|
||||||
|
|
||||||
struct ircd::m::sync::args
|
struct ircd::m::sync::args
|
||||||
{
|
{
|
||||||
static conf::item<milliseconds> timeout_max;
|
static conf::item<milliseconds> timeout_max;
|
||||||
static conf::item<milliseconds> timeout_min;
|
static conf::item<milliseconds> timeout_min;
|
||||||
static conf::item<milliseconds> timeout_default;
|
static conf::item<milliseconds> timeout_default;
|
||||||
|
|
||||||
const resource::request &request;
|
/// 6.2.1 The ID of a filter created using the filter API or a filter JSON object
|
||||||
|
/// encoded as a string. The server will detect whether it is an ID or a JSON object
|
||||||
|
/// by whether the first character is a "{" open brace. Passing the JSON inline is best
|
||||||
|
/// suited to one off requests. Creating a filter using the filter API is recommended
|
||||||
|
/// for clients that reuse the same filter multiple times, for example in long poll requests.
|
||||||
|
string_view filter_id;
|
||||||
|
|
||||||
string_view filter_id
|
/// Parse the since token string; this may be two numbers separated by '_'
|
||||||
{
|
/// or it may be one number, or none. defaults to '0' for initial_sync.
|
||||||
// 6.2.1 The ID of a filter created using the filter API or a filter JSON object
|
/// The second number is used as a next_batch value cookie we gave to
|
||||||
// encoded as a string. The server will detect whether it is an ID or a JSON object
|
/// the client (used during phased polylog sync)
|
||||||
// by whether the first character is a "{" open brace. Passing the JSON inline is best
|
std::pair<string_view, string_view> since_token;
|
||||||
// suited to one off requests. Creating a filter using the filter API is recommended
|
|
||||||
// for clients that reuse the same filter multiple times, for example in long poll requests.
|
|
||||||
request.query["filter"]
|
|
||||||
};
|
|
||||||
|
|
||||||
std::pair<string_view, string_view> since_token
|
/// 6.2.1 A point in time to continue a sync from.
|
||||||
{
|
uint64_t since;
|
||||||
// parse the since token string; this may be two numbers separated by '_'
|
|
||||||
// or it may be one number, or none. defaults to '0' for initial_sync.
|
|
||||||
// The second number is used as a next_batch value cookie we gave to
|
|
||||||
// the client (used during phased polylog sync)
|
|
||||||
split(request.query.get("since", "0"_sv), '_')
|
|
||||||
};
|
|
||||||
|
|
||||||
uint64_t since
|
/// This is the raw (non-spec) next_batch token which can be supplied by
|
||||||
{
|
/// the client as an upper-bound on the window of this sync operation.
|
||||||
// 6.2.1 A point in time to continue a sync from.
|
/// If this is non-empty, the value takes precedence and will be strictly
|
||||||
lex_cast<uint64_t>(since_token.first)
|
/// adhered to. Otherwise, the next_batch below may be computed by the
|
||||||
};
|
/// server and may be violated on longpolls.
|
||||||
|
string_view next_batch_token;
|
||||||
|
|
||||||
// This is the raw (non-spec) next_batch token which can be supplied by
|
/// This is named the same as the next_batch response value passed to the
|
||||||
// the client as an upper-bound on the window of this sync operation.
|
/// client at the conclusion of the sync operation because it will literally
|
||||||
// If this is non-empty, the value takes precedence and will be strictly
|
/// pass through this value. The next sync operation will then start at this
|
||||||
// adhered to. Otherwise, the next_batch below may be computed by the
|
/// value. This token is an event_idx, like the since token. Note it may point
|
||||||
// server and may be violated on longpolls.
|
/// to an event that does not yet exist past-the-end.
|
||||||
string_view next_batch_token
|
uint64_t next_batch;
|
||||||
{
|
|
||||||
request.query.get("next_batch", since_token.second)
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is named the same as the next_batch response value passed to the
|
/// The point in time at which this /sync should stop longpolling and return
|
||||||
// client at the conclusion of the sync operation because it will literally
|
/// an empty'ish response to the client.
|
||||||
// pass through this value. The next sync operation will then start at this
|
steady_point timesout;
|
||||||
// value. This token is an event_idx, like the since token. Note it may point
|
|
||||||
// to an event that does not yet exist past-the-end.
|
|
||||||
uint64_t next_batch
|
|
||||||
{
|
|
||||||
// [experimental] A upper bound to stop this sync at. This is used in
|
|
||||||
// conjunction with `since` to provide a stable window of results. If
|
|
||||||
// not specified the sync range is everything after `since`. NOTE that
|
|
||||||
// this DOES NOT guarantee true idempotency in all cases and for all
|
|
||||||
// time. But that would be nice. Many sync modules do not support this
|
|
||||||
// because the results of repeated calls for range may become empty
|
|
||||||
// after a while.
|
|
||||||
uint64_t(lex_cast<int64_t>(next_batch_token?: "-1"_sv))
|
|
||||||
};
|
|
||||||
|
|
||||||
steady_point timesout{[this]
|
/// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
|
||||||
{
|
/// If this is set to true, then all state events will be returned, even if since is non-empty.
|
||||||
// 6.2.1 The maximum time to poll in milliseconds before returning this request.
|
/// The timeline will still be limited by the since parameter. In this case, the timeout
|
||||||
auto ret(request.query.get("timeout", milliseconds(timeout_default)));
|
/// parameter will be ignored and the query will return immediately, possibly with an
|
||||||
ret = std::min(ret, milliseconds(timeout_max));
|
/// empty timeline. If false, and since is non-empty, only state which has changed since
|
||||||
ret = std::max(ret, milliseconds(timeout_min));
|
/// the point indicated by since will be returned. By default, this is false.
|
||||||
return now<steady_point>() + ret;
|
bool full_state;
|
||||||
}()};
|
|
||||||
|
|
||||||
bool full_state
|
/// 6.2.1 Controls whether the client is automatically marked as online by polling this API.
|
||||||
{
|
/// If this parameter is omitted then the client is automatically marked as online when it
|
||||||
// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
|
/// uses this API. Otherwise if the parameter is set to "offline" then the client is not
|
||||||
// If this is set to true, then all state events will be returned, even if since is non-empty.
|
/// marked as being online when it uses this API. One of: ["offline"]
|
||||||
// The timeline will still be limited by the since parameter. In this case, the timeout
|
bool set_presence;
|
||||||
// parameter will be ignored and the query will return immediately, possibly with an
|
|
||||||
// empty timeline. If false, and since is non-empty, only state which has changed since
|
|
||||||
// the point indicated by since will be returned. By default, this is false.
|
|
||||||
request.query.get("full_state", false)
|
|
||||||
};
|
|
||||||
|
|
||||||
bool set_presence
|
|
||||||
{
|
|
||||||
// 6.2.1 Controls whether the client is automatically marked as online by polling this API.
|
|
||||||
// If this parameter is omitted then the client is automatically marked as online when it
|
|
||||||
// uses this API. Otherwise if the parameter is set to "offline" then the client is not
|
|
||||||
// marked as being online when it uses this API. One of: ["offline"]
|
|
||||||
request.query.get("set_presence", true)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// (non-spec) Controls whether to enable phased-polylog-initial-sync, also
|
/// (non-spec) Controls whether to enable phased-polylog-initial-sync, also
|
||||||
/// known as Crazy-Loading. This is enabled by default, but a query string
|
/// known as Crazy-Loading. This is enabled by default, but a query string
|
||||||
/// of `?phased=0` will disable it for synapse-like behavior.
|
/// of `?phased=0` will disable it for synapse-like behavior.
|
||||||
bool phased
|
bool phased;
|
||||||
{
|
|
||||||
request.query.get("phased", true)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// (non-spec) If this is set to true, the only response content from /sync
|
/// (non-spec) If this is set to true, the only response content from /sync
|
||||||
/// will be a `next_batch` token. This is useful for clients that only want
|
/// will be a `next_batch` token. This is useful for clients that only want
|
||||||
/// to use /sync as a semaphore notifying about new activity, but will
|
/// to use /sync as a semaphore notifying about new activity, but will
|
||||||
/// retrieve the actual data another way.
|
/// retrieve the actual data another way.
|
||||||
bool semaphore
|
bool semaphore;
|
||||||
{
|
|
||||||
request.query.get("semaphore", false)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/// Constructed by the GET /sync request method handler on its stack.
|
||||||
args(const resource::request &request);
|
args(const resource::request &request);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue