Repository navigation
Automatic reduction is a batch reduced as its files arrive - #196
Open
SimonHeybrock wants to merge 7 commits into
Open
SimonHeybrock wants to merge 7 commits into
SimonHeybrock wants to merge 7 commits into
Conversation
`Batch.state(settings, keys)` reads the records and statuses of the rows of `keys` only, and `reduce`, `tweak`, and `cancel` use it, so that submitting a few rows of a batch of 100k rows no longer works out the state of every row. A table without edits returns the scan's rows as they are, without a copy per row. A row's result is the newest record of the batch's spec, label, and the row's key, whoever submitted it: one folder or one service holds one history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`ess.apps.batch.auto.Automatic(batch, at=, settings=)` steps one batch: it scans, and reduces each row whose cell at the trigger column `at` holds a file that no record under the batch's label with the row's key holds at `at`. So a failed record, a changed setting, or a new partner does not reduce a row again, and a new file in a list at `at` does. Which files the records hold is read from the proposal's changes, so a restart needs nothing on disk. A row that is refused does not hold back the others, and `refused` says why. A step looks at the rows whose cells or records changed, and at the refused rows when the settings change. `run(autos, interval)` steps a list of them in order, so that a batch whose source reads another's results comes after it. `ess.apps.rules` (`Rule`, `RuleStatus`, `TriggerLoop`) is removed: a technique writes its pairing once, as the source of a batch. The stories E and the test of a moved folder use the batch. The check that a file at a list parameter is refused moves to the tests of requests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
automatic-reduction.md describes the loop over batches: which rows run and why, what the loop keeps, refusals, chains across batches, the cost of a step, and what is open (new files since a position, a group per file, a range in Selector, old rows reduced again for a new spec version). The batch guide gains a section on the automatic use, with the table of which rows run for "reduce remaining", `essapps-batch reduce --remaining`, and the loop, and says that a source may read another batch's state. A row's result no longer depends on the submitter. Stories E, the README, deployments, the ADRs, the prior-art notes, the client guide, and the tours name the batch where they named rules and the trigger loop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A step worked out which rows to look at from what changed since the last step, and stored that before it submitted, so an exception in the settings, the source, or a submission left a row unreduced until it changed again. A step now checks every row's cell at the trigger column against the files the records hold, which come from the records only. The rows refused are kept as they were then, and are tried again once their cells, their records, or the settings change. The check reads the cell directly, a file or a list of files, which costs less than comparing the rows with those of the last step. `Automatic` refuses a batch without a source. `Batch.state(keys=...)` gives the same state of a row as `Batch.state()` when a cell references an unknown record: only the rows that reference it lose the status of the records they read. A row given with `EMPTY` in its values has that cell empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two file references are equal only when their identity strings are, so the files held at the trigger column are kept as those strings. Checking a row then hashes a string instead of a pydantic model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
automatic-reduction.md states the scale that the cost is measured against, how the interval of `run` sets the load, why the history is not cut off by age or count, and what a step keeps now that it checks every row. It no longer says that the state of chosen rows reads only their records. Open gains: reading the records of chosen members, a source that makes a row from one file by queries on an index of the files, the files held at the trigger column for a page, and a trigger cell that names a file by run number. The batch guide calls an `Automatic` the loop, keeps "automatic reduction" for the activity, and says that which rows are reduced is defined by the records under the label only, so a new label reduces from the first file and a row whose key changes is reduced again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cell at the trigger column that names a file, such as `file(run=1)`, is resolved by the workspace, so its record holds the file's identity and never counts as holding the cell: the row was reduced at every step. A client has no call that resolves a file name, so the loop checks, for the rows it submitted, that each record holds the files of its row's cell, and raises `ValueError` naming the row if one does not. Every later step raises too, before it submits anything, until that cell changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 of 7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 4 of #184, first part: automatic reduction and batch reduction are one model.
ess.apps.rules(Rule,RuleStatus,TriggerLoop) is removed. Automatic reduction is aBatchthatess.apps.batch.auto.Automaticreduces as its files arrive.Why
Rules predate the batch. A rule's
submit(client, file)did three things in one function per file: pair the file with its partners, decide whether the file was handled, and submit. The batch has the first as a row source (a function from the files to rows, tested on plain data) and the third asBatch.reduce. So a technique wrote its pairing twice, once as a row source and once as a rule function, and automatic reduction had none of what the batch gives: a state per row that says why a run waits, a stage for what the rows share, and the views.Which rows run
A person and the automatic reduction differ in one predicate over the same join of rows with the records under the batch's label:
essapps-batch reduce --remainingAutomaticAutomaticreads which files the records of each row hold at the trigger column from the proposal's changes, so a restart needs nothing on disk. Records of any spec and any submitter count. A new label has no records, so it reduces from the first file.What behaves differently from rules
Automaticdrops the rows a refusal names and submits the rest.Batch.reducestays all or none for a person.FileInfo.ref. A cell that names a file, such asfile(run=1), would never match what its record holds, and a client has no call to resolve the name.stepraisesValueErrorfor such a row after its first record, and at every later step before it submits. This takes the place of the check that a rule's record settles its file.Changes to the batch
Batch.state(settings=None, keys=None)works out the state of chosen rows, so thatreducedoes not work out every row. It still reads every record under the label.state.resultsdoes not filter by submitter: one folder or one service holds one history.Cost
The requirement, from Simon: some instruments will write a file every few seconds, so 10 000 to 100 000 files per proposal. One step with one new file, toy workflow, fake file source, on a shared machine:
A step is linear in the number of files: it lists them, runs the source over them, and checks each row against the files its records hold.
TriggerLoopwas linear too (272 ms at 100 000), since it listed all files at each step. A step costs the same for one new file or fifty, so the interval ofrunsets the load. The mean is about twice the best because of Python's garbage collector.docs/developer/automatic-reduction.mdlists what is open and not built: a file source that reports what is new since a position; two ways to make a step cost less than linear (a group per file that the source's author declares, or a source that makes one row by queries on an index that records what each row asked for); a range inSelectorto start a new label at a given run; running old rows again for a new spec version; reading the records of chosen rows only. It also says why the history is not cut off by age or count to bound the cost.Known limits
Batch.state, which counts results of the batch's spec version only, whileAutomaticcounts any record under the label. After a new spec version a view would show old rows as not reduced whileAutomaticholds them. Related to What a batch is: how its definition is tied to its records #191.Batchkeeps each submitted request in memory for "stale" (What a batch is: how its definition is tied to its records #191), so a long-runningAutomaticholds one request per row.state()works out every row of that batch at each step.runhas no test.Review
A fresh reviewer probed the branch and mutated the code. Fixed from it: a step that raised lost its rows until a restart; a trigger cell that named a file was submitted at every step; cost statements that were false;
state(keys=...)differing fromstate()for a row; documented behaviours with no test that failed when they broke.Remaining in step 4 of #184: one batch presenter, and one plot contract for technique packages (#149).
🤖 Generated with Claude Code