Commit 94fc4a6
Roll an hour up without letting it lose one of its three states (#28)
* Roll an hour up without letting it lose one of its three states
presence_sample has been partitioned monthly since 0003 for rollups and
retention that nobody had written. This writes them.
The rollup keeps the tally and not the conclusion: presence_rollup_hour and
presence_rollup_day carry counted and uncountable sample counts separately,
min/max/mean over the counted ones alone, and no row at all for an hour nobody
measured. A measured zero is a filled cell, a probe that got in and could not
count is a hatched one, and an hour we never reached is the absence of a row --
the same three states the raw table keeps, after aggregation. The CHECK
constraints refuse a bucket with a zero it did not measure and a bucket that
claims to be a measurement of nothing.
Partitions are now made ahead of need as well as before every append, so a
month ending is never the first thing to discover a database we cannot write
DDL to. The pass runs behind its own Postgres advisory lock, like the crawl
loop -- CrawlLease is renamed AdvisoryLease, since two workers now share it.
Retention is configuration, because 15.4 is open. It keeps everything at every
grain by default, with 5.2's own figures a preset away, and it never runs ahead
of the rollup: raw months go whole, and only once both grains have consumed
them. 15.4 records the choice as ship conservative and tune.
Salt rotation, which 11 promised and nothing implemented: a per-epoch HMAC salt
derived from a deployment secret, an epoch label recorded beside every
aggregate, and a rollup that refuses to combine an estimate across a rotation
rather than publishing a bigger number. Names go in and sixteen bytes come out;
nothing persists a name.
Testcontainers 4.13 pulls SSH.NET 2025.1.0, which now has an advisory, and
TreatWarningsAsErrors turns that into a broken restore for everyone. Bumped.
* Let each grain remember for itself how far it has read
The daily rollup resumed from the hourly watermark, which is fine right up
until the two statements do not both run. A pass that rolled the hours,
committed their watermark and then died left the days unwritten -- and the next
pass, reading the hourly mark, skipped everything older than the overlap, wrote
its own watermark as though it had read it, and let retention drop the raw
months behind it. Six days of history came back as six hour buckets and one day
bucket, and then the raw rows went. The grain 5.2 keeps for ever, missing, with
the only other copy deleted.
Each grain now resumes from its own watermark and writes that watermark only
after its own aggregation, so an interrupted pass resumes instead of skipping,
and retention still waits for whichever grain is behind.
An estimate with no salt epoch also cost more than itself: the invariant ran
inside JSON deserialisation, so one such row threw out of the middle of a read
and took the whole window with it, while the aggregation read the same row
without complaint. The reader now drops the estimate and keeps the buckets, and
the SQL filters the same case, so both paths agree that an unlabelled estimate
is not one anything may compare with another.
The maintenance service starts beside the crawler's migration run rather than
after it, so it asks whether the schema is there instead of finding out as a
42P01 and standing down for five minutes.
11's salt machinery is in place and nothing feeds it: the WHO parser counts
rows and never extracts a name, so no probe produces aggregates. Said plainly
in 5.2 and beside the registration, rather than left to read as delivered.
---------
Co-authored-by: Harry Cordewener <nekomercutio@gmail.com>1 parent fcca6db commit 94fc4a6
22 files changed
Lines changed: 2575 additions & 56 deletions
File tree
- docs/specs
- migrations
- src
- MUI.Catalog
- Persistence
- MUI.Crawler
- MUI.Crawl
- tests
- MUI.Catalog.Tests
- Persistence
- MUI.Crawl.Tests
- MUI.Crawler.Tests
- Support
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
233 | 259 | | |
234 | 260 | | |
235 | 261 | | |
| |||
1095 | 1121 | | |
1096 | 1122 | | |
1097 | 1123 | | |
1098 | | - | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
1099 | 1139 | | |
1100 | 1140 | | |
1101 | 1141 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
4 | 6 | | |
5 | 7 | | |
6 | 8 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
0 commit comments