Gates / frontend (push) Successful in 2m6s
Gates / test (push) Successful in 2m57s
Gates / test-aarch64 (push) Successful in 8m31s
Gates / package (push) Successful in 4m19s
Gates / container (push) Failing after 2s
CI / gates (push) Failing after 26m21s
56 lines
2.1 KiB
Zig
56 lines
2.1 KiB
Zig
//! How much of the window a client asked about the query log can still answer
|
|
//! for.
|
|
//!
|
|
//! Retention deletes old rows and advances a watermark in the same transaction
|
|
//! (`queries_repo.pruneOlderThan`), so the file knows the oldest instant it is
|
|
//! complete for. Without that fact on the wire a chart draws a pruned week as a
|
|
//! week of silence, which is the one reading that is certainly wrong.
|
|
//!
|
|
//! Two endpoints carry it — `/api/queries` and `/api/overview` — and they judge
|
|
//! it against their own effective lower bound: the client's `since` for the
|
|
//! query log, the period's aligned window start for the overview.
|
|
|
|
const std = @import("std");
|
|
|
|
const db = @import("../storage/db.zig");
|
|
const queries_repo = @import("../storage/repositories/queries_repo.zig");
|
|
|
|
pub const Coverage = struct {
|
|
/// True only when the whole requested window is inside what the file still
|
|
/// holds. A request with no lower bound at all asks about all of history,
|
|
/// which no file that has ever pruned can promise.
|
|
complete: bool,
|
|
/// The oldest instant the file is complete for, unix seconds.
|
|
available_since: i64,
|
|
};
|
|
|
|
pub fn of(available_since: i64, since: ?i64) Coverage {
|
|
return .{
|
|
.complete = if (since) |lower_bound| lower_bound >= available_since else false,
|
|
.available_since = available_since,
|
|
};
|
|
}
|
|
|
|
/// Reads the watermark for a request that is about to answer.
|
|
pub fn read(database: *db.Db, since: ?i64) db.Error!Coverage {
|
|
return of(try queries_repo.availableSince(database), since);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// tests
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const testing = std.testing;
|
|
|
|
test "a window that starts at or after the watermark is complete" {
|
|
try testing.expect(of(1000, 1000).complete);
|
|
try testing.expect(of(1000, 1001).complete);
|
|
try testing.expect(!of(1000, 999).complete);
|
|
}
|
|
|
|
test "an unbounded window is never complete" {
|
|
const unbounded = of(1000, null);
|
|
try testing.expect(!unbounded.complete);
|
|
try testing.expectEqual(@as(i64, 1000), unbounded.available_since);
|
|
}
|