From 6495fa55d5276a680b6c407151b0f49d4497ccc9 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 2 Aug 2019 14:14:02 -0700 Subject: [PATCH] modules/client/sync: Move the sync::args ctor definition into unit. --- modules/client/sync.cc | 105 ++++++++++++++++++++--------- modules/client/sync/args.h | 131 ++++++++++++++----------------------- 2 files changed, 122 insertions(+), 114 deletions(-) diff --git a/modules/client/sync.cc b/modules/client/sync.cc index 51f9a9376..2c5cf23b5 100644 --- a/modules/client/sync.cc +++ b/modules/client/sync.cc @@ -119,31 +119,6 @@ ircd::m::sync::longpoll_enable { "default", true }, }; -// -// sync/args.h -// - -ircd::conf::item -ircd::m::sync::args::timeout_max -{ - { "name", "ircd.client.sync.timeout.max" }, - { "default", 180 * 1000L }, -}; - -ircd::conf::item -ircd::m::sync::args::timeout_min -{ - { "name", "ircd.client.sync.timeout.min" }, - { "default", 15 * 1000L }, -}; - -ircd::conf::item -ircd::m::sync::args::timeout_default -{ - { "name", "ircd.client.sync.timeout.default" }, - { "default", 90 * 1000L }, -}; - // // GET sync // @@ -1026,22 +1001,90 @@ noexcept { } +// +// sync/args.h +// + +ircd::conf::item +ircd::m::sync::args::timeout_max +{ + { "name", "ircd.client.sync.timeout.max" }, + { "default", 180 * 1000L }, +}; + +ircd::conf::item +ircd::m::sync::args::timeout_min +{ + { "name", "ircd.client.sync.timeout.min" }, + { "default", 15 * 1000L }, +}; + +ircd::conf::item +ircd::m::sync::args::timeout_default +{ + { "name", "ircd.client.sync.timeout.default" }, + { "default", 90 * 1000L }, +}; + // // args::args // ircd::m::sync::args::args(const resource::request &request) try -:request +:filter_id { - request + request.query["filter"] +} +,since_token +{ + split(request.query.get("since", "0"_sv), '_') +} +,since +{ + lex_cast(since_token.first) +} +,next_batch_token +{ + request.query.get("next_batch", since_token.second) +} +,next_batch +{ + uint64_t(lex_cast(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() + 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) { - throw m::BAD_REQUEST - { - "Since parameter invalid :%s", e.what() - }; + throw m::BAD_REQUEST + { + "Since parameter invalid :%s", e.what() + }; } diff --git a/modules/client/sync/args.h b/modules/client/sync/args.h index f0283685e..152ee114f 100644 --- a/modules/client/sync/args.h +++ b/modules/client/sync/args.h @@ -8,111 +8,76 @@ // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. +namespace ircd::m::sync +{ + struct args; +} + struct ircd::m::sync::args { static conf::item timeout_max; static conf::item timeout_min; static conf::item 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 - { - // 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. - request.query["filter"] - }; + /// 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) + std::pair since_token; - std::pair since_token - { - // 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), '_') - }; + /// 6.2.1 A point in time to continue a sync from. + uint64_t since; - uint64_t since - { - // 6.2.1 A point in time to continue a sync from. - lex_cast(since_token.first) - }; + /// 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. + /// If this is non-empty, the value takes precedence and will be strictly + /// 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 - // the client as an upper-bound on the window of this sync operation. - // If this is non-empty, the value takes precedence and will be strictly - // adhered to. Otherwise, the next_batch below may be computed by the - // server and may be violated on longpolls. - string_view next_batch_token - { - request.query.get("next_batch", since_token.second) - }; + /// This is named the same as the next_batch response value passed to the + /// client at the conclusion of the sync operation because it will literally + /// pass through this value. The next sync operation will then start at this + /// 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; - // This is named the same as the next_batch response value passed to the - // client at the conclusion of the sync operation because it will literally - // pass through this value. The next sync operation will then start at this - // 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(next_batch_token?: "-1"_sv)) - }; + /// The point in time at which this /sync should stop longpolling and return + /// an empty'ish response to the client. + steady_point timesout; - steady_point timesout{[this] - { - // 6.2.1 The maximum time to poll in milliseconds before returning this 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() + ret; - }()}; + /// 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. + /// The timeline will still be limited by the since parameter. In this case, the timeout + /// 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. + bool full_state; - bool full_state - { - // 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. - // The timeline will still be limited by the since parameter. In this case, the timeout - // 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) - }; + /// 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"] + bool set_presence; /// (non-spec) Controls whether to enable phased-polylog-initial-sync, also /// known as Crazy-Loading. This is enabled by default, but a query string /// of `?phased=0` will disable it for synapse-like behavior. - bool phased - { - request.query.get("phased", true) - }; + bool phased; /// (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 /// to use /sync as a semaphore notifying about new activity, but will /// retrieve the actual data another way. - bool semaphore - { - request.query.get("semaphore", false) - }; + bool semaphore; + /// Constructed by the GET /sync request method handler on its stack. args(const resource::request &request); };