about summary refs log tree commit diff
path: root/README.md
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2019-12-04T10·42+0100
committerFlorian Klink <flokli@flokli.de>2019-12-04T10·43+0100
commit0ec77274f556ee06be8350b586b7f2f533e508e9 (patch)
tree884df3bcbbb4e48b5011df58a029e4810f194541 /README.md
parent2a4d5516e46277172a8a7be5a747651330469e99 (diff)
README: document current runner logic in detail
Diffstat (limited to 'README.md')
-rw-r--r--README.md71
1 files changed, 51 insertions, 20 deletions
diff --git a/README.md b/README.md
index 2b6c160d41bb..d021fd025ccb 100644
--- a/README.md
+++ b/README.md
@@ -6,41 +6,72 @@ instance, ensuring they still pass CI.
 In a usual gerrit setup with a linear master history, different developers
 await CI feedback on a rebased changeset, then one clicks submit, and
 effectively makes everybody else rebase again. `gerrit-queue` is meant to
-remove these races to master. Developers can add a specific tag to a changeset,
-and if all preconditions are met (passing CI and passing Code Review),
-`gerrit-queue` takes care of rebasing and submitting it to master.
+remove these races to master.
+
+Developers can add a specific tag `submit_me` to all changesets in a series,
+and if all preconditions on are met ("submittable" in gerrit speech, this
+usually means passing CI and passing Code Review), `gerrit-queue` takes care of
+rebasing and submitting it to master
 
 ## How it works
 Gerrit only knows about Changesets (and some relations to other changesets),
 but usually developers think in terms of multiple changesets.
 
-### The Fetching Phase
+### Fetching changesets
 `gerrit-queue` fetches all changesets from gerrit, and tries to identify these
 chains of changesets. We call them `Series`. All changesets need to have strict
-parent/child relationships to be detected.
+parent/child relationships to be detected (so if only half of the stack gets
+rebased by the Gerrit Web interface, these are considered individual series.
 
-Series are ordered by the number of changesets in them. This ensures longer
+Series are sorted by the number of changesets in them. This ensures longer
 series are merged faster, and less rebases are triggered. In the future, this
 might be extended to other metrics.
 
-### The Submit Phase
-We loop over all series. If all changesets of a given series pass the required
-preconditions (passing CI, passing Code Review, autosubmit Tag) and it's
-rebased on top of the current destination branch's HEAD, it can be submitted.
+### Submitting changesets
+The submitqueue has a Trigger() function, which gets periodically executed.
+
+It can keep a reference to one single serie across multiple runs. This is
+necessary if it previously rebased one serie to current HEAD and needs to wait
+some time until CI feedback is there. If it wouldn't keep that state, it would
+pick another series (with +1 from CI) and trigger a rebase on that one, so
+depending on CI run times and trigger intervals, if not keepig this information
+it'd end up rebasing all unrebased changesets on the same HEAD, and then just
+pick one, instead of waiting for the one to finish.
+
+The Trigger() function first instructs the gerrit client to fetch changesets
+and assemble series.
+If there is a `wipSerie` from a previous run, we check if it can still be found
+in the newly assembled list of series (it still needs to contain the same
+number of series. Commit IDs may differ, because the code doesn't reassemble a
+`wipSerie` after scheduling a rebase.
+If the `wipSerie` could be refreshed, we update the pointer with the newly
+assembled series. If we couldn't find it, we drop it.
+
+Now, we enter the main for loop. The first half of the loop checks various
+conditions of the current `wipSerie`, and if successful, does the submit
+("Submit phase"), the second half will pick a suitable new `wipSerie`, and
+potentially do a rebase ("Pick phase").
+
+#### Submit phase
+We check if there is an existing `wipSerie`. If there isn't, we immediately go to
+the "pick" phase.
 
-The current serie is removed from the list of series, and we update our HEAD to
-the commit ID of the last commit in the submitted series.
+The `wipSerie` still needs to be rebased on `HEAD` (otherwise, the submit queue
+advanced outside of gerrit), and should not fail CI (logical merge conflict) -
+otherwise we discard it, and continue with the picking phase.
 
-### The Rebase Phase
-We loop over all remaining series. The first one matching the required
-preconditions is rebased on top of the (advanced HEAD) (and if this fails, we
-skip and keep trying with the next Series one after another).
+If the `wipSerie` still contains a changeset awaiting CI feedback, we `return`
+from the `Trigger()` function (and go back to sleep).
 
+If the changeset is "submittable" in gerrit speech, and has the necessary
+submit queue tag set, we submit it.
 
-These three phases are designed to be stateless, and currently triggered once
-per run.
-This is supposed to be moved to a more reactive model, so that the submit phase
-is triggered by Webhooks for CI feedback, and we don't rebase too often
+#### Pick phase
+The pick phase finds a new `wipSerie`. It'll first try to find one that already
+is rebased on the current `HEAD` (so the loop can just continue, and the next
+submit phase simply submit), and otherwise fall back to a not-yet-rebased
+serie. Because the rebase mandates waiting for CI, the code `return`s the
+`Trigger()` function, so it'll be called again after waiting some time.
 
 ## Compile and Run
 ```sh