Skip to content

Commit 23b6d79

Browse files
committed
protocol: add query option CONTINUE
1 parent 7e1924d commit 23b6d79

File tree

5 files changed

+58
-11
lines changed

5 files changed

+58
-11
lines changed

debian/changelog

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cm4all-pond (0.35) unstable; urgency=low
22

3+
* protocol: add query option CONTINUE
34
* client: show REMOTE_HOST in message lines
45
* client: support ISO8601 time stamps in message lines
56
* client: show Conten-Type in JSONL response

src/Connection.cxx

+29-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Connection::Request::Clear() noexcept
2424
group_site.max_sites = 0;
2525
window.max = 0;
2626
follow = false;
27+
continue_ = false;
2728
selection.reset();
2829
address.clear();
2930
}
@@ -318,7 +319,8 @@ try {
318319

319320
case PondRequestCommand::FOLLOW:
320321
if (!current.MatchId(id) ||
321-
current.command != PondRequestCommand::QUERY)
322+
current.command != PondRequestCommand::QUERY ||
323+
current.continue_)
322324
throw SimplePondError{"Misplaced FOLLOW"};
323325

324326
if (current.follow)
@@ -344,8 +346,8 @@ try {
344346
if (!current.filter.sites.empty())
345347
throw SimplePondError{"FILTER_SITE and GROUP_SITE are mutually exclusive"};
346348

347-
if (current.follow)
348-
throw SimplePondError{"FOLLOW and GROUP_SITE are mutually exclusive"};
349+
if (current.follow || current.continue_)
350+
throw SimplePondError{"FOLLOW/CONTINUE and GROUP_SITE are mutually exclusive"};
349351

350352
if (current.group_site.max_sites > 0)
351353
throw SimplePondError{"Duplicate GROUP_SITE"};
@@ -404,8 +406,8 @@ try {
404406
current.command != PondRequestCommand::QUERY)
405407
throw SimplePondError{"Misplaced WINDOW"};
406408

407-
if (current.follow)
408-
throw SimplePondError{"FOLLOW and WINDOW are mutually exclusive"};
409+
if (current.follow || current.continue_)
410+
throw SimplePondError{"FOLLOW/CONTINUE and WINDOW are mutually exclusive"};
409411

410412
if (current.HasWindow())
411413
throw SimplePondError{"Duplicate WINDOW"};
@@ -500,6 +502,27 @@ try {
500502
if (!current.filter.duration.HasLonger())
501503
throw SimplePondError{"Malformed FILTER_DURATION_LONGER"};
502504
return BufferedResult::AGAIN;
505+
506+
case PondRequestCommand::CONTINUE:
507+
if (!current.MatchId(id) ||
508+
current.command != PondRequestCommand::QUERY ||
509+
current.follow)
510+
throw SimplePondError{"Misplaced CONTINUE"};
511+
512+
if (current.continue_)
513+
throw SimplePondError{"Duplicate CONTINUE"};
514+
515+
if (current.HasGroupSite())
516+
throw SimplePondError{"CONTINUE and GROUP_SITE are mutually exclusive"};
517+
518+
if (current.HasWindow())
519+
throw SimplePondError{"CONTINUE and WINDOW are mutually exclusive"};
520+
521+
if (!payload.empty())
522+
throw SimplePondError{"Malformed CONTINUE"};
523+
524+
current.continue_ = true;
525+
return BufferedResult::AGAIN;
503526
}
504527

505528
throw SimplePondError{"Command not implemented"};
@@ -676,7 +699,7 @@ Connection::OnBufferedWrite()
676699
/* no more sites, end this response */
677700
}
678701

679-
if (current.follow) {
702+
if (current.follow || current.continue_) {
680703
current.selection->AddAppendListener(*this);
681704
} else {
682705
Send(current.id, PondResponseCommand::END, {});

src/Connection.hxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Connection final
3535

3636
struct Request {
3737
uint16_t id = 0;
38-
bool follow = false;
38+
bool follow = false, continue_ = false;
3939
PondRequestCommand command = PondRequestCommand::NOP;
4040

4141
Filter filter;

src/Protocol.hxx

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ enum class PondRequestCommand : uint16_t {
3535
* Option for #QUERY which follows incoming new records
3636
* instead of printing past ones. The response never ends
3737
* until the client sends #CANCEL (or closes the connection).
38+
*
39+
* This is similar to #CONTINUE, but only prints new records.
3840
*/
3941
FOLLOW = 5,
4042

@@ -127,6 +129,16 @@ enum class PondRequestCommand : uint16_t {
127129
* a 64 bit unsigned integer [microseconds].
128130
*/
129131
FILTER_DURATION_LONGER = 19,
132+
133+
/**
134+
* Option for #QUERY which follows incoming new records after
135+
* printing past ones. The response never ends until the
136+
* client sends #CANCEL (or closes the connection).
137+
*
138+
* This is similar to #FOLLOW, but also prints matching past
139+
* records.
140+
*/
141+
CONTINUE = 20,
130142
};
131143

132144
enum class PondResponseCommand : uint16_t {

src/client/Main.cxx

+15-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct QueryOptions {
6565

6666
bool jsonl = false;
6767

68-
bool follow = false;
68+
bool follow = false, continue_ = false;
6969
bool raw = false;
7070
bool gzip = false;
7171
#ifdef HAVE_LIBGEOIP
@@ -202,9 +202,17 @@ ParseFilterItem(Filter &filter, PondGroupSitePayload &group_site,
202202
options.per_site_filename = per_site_filename;
203203
} else if (StringIsEqual(p, "--per-site-nested")) {
204204
options.per_site_nested = true;
205-
} else if (StringIsEqual(p, "--follow"))
205+
} else if (StringIsEqual(p, "--follow")) {
206+
if (options.continue_)
207+
throw "Cannot use both --follow and --continue";
208+
206209
options.follow = true;
207-
else if (StringIsEqual(p, "--raw"))
210+
} else if (StringIsEqual(p, "--continue")) {
211+
if (options.follow)
212+
throw "Cannot use both --follow and --continue";
213+
214+
options.continue_ = true;
215+
} else if (StringIsEqual(p, "--raw"))
208216
options.raw = true;
209217
else if (StringIsEqual(p, "--gzip"))
210218
options.gzip = true;
@@ -364,6 +372,9 @@ Query(const PondServerSpecification &server, ConstBuffer<const char *> args)
364372
if (options.follow)
365373
client.Send(id, PondRequestCommand::FOLLOW);
366374

375+
if (options.continue_)
376+
client.Send(id, PondRequestCommand::CONTINUE);
377+
367378
client.Send(id, PondRequestCommand::COMMIT);
368379

369380
struct pollfd pfds[] = {
@@ -588,7 +599,7 @@ try {
588599
"\n"
589600
"Commands:\n"
590601
" query\n"
591-
" [--follow]\n"
602+
" [--follow] [--continue]\n"
592603
" [--raw] [--gzip]\n"
593604
#ifdef HAVE_LIBGEOIP
594605
" [--geoip]\n"

0 commit comments

Comments
 (0)