diff --git a/modules/client/sync.cc b/modules/client/sync.cc index 018fc6686..efaf84366 100644 --- a/modules/client/sync.cc +++ b/modules/client/sync.cc @@ -442,11 +442,32 @@ try int64_t(data.range.second) }; + char buf[48]; + const string_view &next_batch_token + { + // The polylog phased since token. We pack two numbers separted by a '_' + // character which cannot be urlencoded atm. The first is the usual + // since token integer, which is negative for phased initial sync. The + // second part is the next_batch upper-bound integer which is a snapshot + // of the server's sequence number when the phased sync started. + data.phased? + fmt::sprintf + { + buf, "%ld_%lu", next_batch, data.range.second + }: + + // The normal integer since token. + fmt::sprintf + { + buf, "%ld", next_batch + } + }; + json::stack::member { *data.out, "next_batch", json::value { - lex_cast(next_batch), json::STRING + next_batch_token ,json::STRING } }; } diff --git a/modules/client/sync/args.h b/modules/client/sync/args.h index 99320a7bf..9ef300534 100644 --- a/modules/client/sync/args.h +++ b/modules/client/sync/args.h @@ -26,10 +26,15 @@ struct ircd::m::sync::args request.query["filter"] }; + std::pair since_token + { + split(request.query.get("since", "0"_sv), '_') + }; + uint64_t since { // 6.2.1 A point in time to continue a sync from. - request.query.get("since", 0) + lex_cast(since_token.first) }; uint64_t next_batch @@ -41,7 +46,7 @@ struct ircd::m::sync::args // 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. - request.query.get("next_batch", -1) + uint64_t(lex_cast(request.query.get("next_batch", since_token.second?: "-1"_sv))) }; steady_point timesout{[this]