0
0
Fork 0
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:
Jason Volk 2019-08-02 14:14:02 -07:00
parent 8e5e599690
commit 6495fa55d5
2 changed files with 122 additions and 114 deletions

View file

@ -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()
}; };
} }

View file

@ -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);
}; };