A cancelled RefreshPeople run discards the stamps it earned #159
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three things left beside
RefreshPeopleafter #154, none of them the defectthat issue was about. Filed together because they are the same two files.
A run that is cancelled discards every stamp it earned.
crates/ephyra-server/src/libraries.rs::refresh_peoplecollects the people nodatabase knew and calls
mark_people_refreshedonce, after the loop. The loopis
cancel.check()?at the top of every iteration, so a cancelled run returnsthrough
?with the batch unwritten — and every person it asked about and foundnothing for is asked about again on the next run. The people it did file are
kept, because those are written as they go.
A person whose row carries an empty name is asked about forever.
people_wanting_a_refreshanswers aWantingfor anyPersonrow whoseNameis not null, empty string included.Write::for_a_namethen refuses it,which is
Refreshed::Failed, which writes no stamp by design — so the row comesback every run. Pre-existing rather than introduced by #154, and it is the one
path
Failedcan loop on rather than retry. The question is whether such a rowshould exist at all:
forget_people_nobody_creditsalready excludesName IS NULL, and an empty name is the same kind of row.mark_people_refreshedisItemWriter::mark_refreshedcopied.crates/ephyra-db/src/scan/people.rsandcrates/ephyra-db/src/items/writes.rs:272are the same statement modulo theType = ?filter. The copy is forced today —placeholdersandBOUND_AT_ONCEare bothpub(super)toitems— but the scan copy spells thebatch size
500as a literal where the other names it.Where to start
The first is the one worth doing: stamp as the loop goes rather than after it,
or write what is pending on the way out. It is the only one of the three that
loses work.
How to know it is done
A
RefreshPeoplerun cancelled halfway leaves the people it already asked aboutstamped, and asks about the rest on the next run rather than all of them.
House rules
CLAUDE.mdis the short version and these are the parts that bite: tests rununder
cargo nextest; upstream's source is the checkout inupstream/at thepin; generated files are regenerated rather than edited; a comment says what
the code does, not how it got there.
A test that cannot fail is worse than none.
Landed in
79d88c3, with review fixes in22de82e. All three.The one that lost work. The loop returns through
?oncancel.check(), sothe batch went with it. It is written on the way out as well as at the end now,
and the loop became
ask_about_people— a function of a resolved databaserather than of the configuration — because stopping a run part way is the only
way to reach that path, and a test cannot do it through the configuration.
The test stands a database up that answers "nobody by that name" and cancels the
run on its first fetch: one person is asked about, the second check fires, and
the stamp has to survive it. It fails against the old shape.
The row with no name.
people_wanting_a_refreshnow gates onTRIM(Name) <> '', which is what the writer trims — the review caught thatName <> ''left a row named with a single space still being refused every runand stamped never. A null name is excluded by the same comparison.
The copy.
mark_people_refreshedreadsBOUND_AT_ONCEandplaceholdersfrom
items, where the statement it was copied from names them, rather thanspelling 500 itself.
One thing the review added: when a stopped run's stamp write also fails, the
loop's error is still the one reported, but the stamp's is logged rather than
dropped silently.