Conversation
Two divergences between what the configuration says and what the pipeline did. `replace` was the share of matching requests that survived the loss roll, not the share of matching requests. The pipeline decided loss and latency first, so `loss: 0.5` with `replace: 0.5` answered a quarter of matching requests from the mock rather than half, and no configuration could ask for half while any loss was set. Mock matching now comes first, and the proxy's `loss` and `latency` no longer touch a request a mock answered -- they describe the real backend, and a mock replaces it. Measured against a running server, 600 requests: 292 mocked, 161 dropped, 147 forwarded, where the old order gave a quarter mocked. A run of slashes at the start of the path is collapsed to one before matching, so `//api/v1/index/` matches a mock declared `^/api/v1/index/$`. A base URL ending in `/` joined to a path beginning with `/` produces that form constantly, it is legal HTTP so nothing rejected it, and an unanchored pattern matched it anyway -- the extra slash falls outside the substring being looked for. Only an anchored pattern failed, silently. Empty segments elsewhere are left alone: whether `/a//b` and `/a/b` name one resource is the upstream's to decide, and answering it here would disagree with the path that gets forwarded. Both verified by mutation. Removing the normalisation fails three tests; restoring the old order fails the mock-beats-loss test. The end-to-end slash test uses an anchored pattern deliberately -- with an unanchored one it passed under the mutation and pinned nothing. Also documents that a mock's `proxy.loss` and `proxy.latency` are parsed, validated and compiled, and then never read. Only `proxy.replace` is applied per mock. The documentation claimed all three were.
An injected delay was added to whatever the upstream took, so the number written in the configuration was never the number a client saw and moved with whatever the backend happened to be doing: `min: 0.5` in front of a backend answering in 120ms produced 620ms. The delay is now a target -- the upstream's real time is subtracted and only the remainder is waited out. Measured against a running server: 503ms total, 375ms of it injected, 124ms of it real. The wait therefore moves to after the response is produced, which is the only place the real time is known. Loss still short-circuits it: a dropped request returns from the loss branch and is never delayed, so refusing a request and then holding the connection open cannot happen. An upstream slower than the target leaves no remainder and is passed straight through -- 900ms upstream under a 500ms target gives 908ms, not 1.4s. The setting is a floor, never a ceiling; Doppel does not make a slow backend look fast. `latency_injected_ms` is the wait actually taken and reads 0 there, while `doppel_latency_injected_total` still counts the request, because the roll did fire. A mock now inherits `latency` from its proxy and overrides rather than adds to it, since the configured latency says how slow this proxy is to answer and that holds whatever answers. Verified live: a mock under a 500ms proxy answers in 503ms, and one overriding with 150ms answers in 153ms rather than 653ms. `loss` remains the one setting a mock does not inherit -- inheriting it would put back the coupling between `loss` and `replace` removed in b4a4009. Both the subtraction and the latency inheritance are pinned by mutation: dropping `saturating_sub` fails two tests, and removing the fallback to the proxy's latency fails a third. The padding arithmetic is unit-tested directly, since the interesting cases are exact numbers and asserting those on wall clock would be a claim about the scheduler.
The site was a single unversioned build, so publishing 0.2.0 replaced 0.1.0's documentation outright and a reader running 0.1.0 had nowhere to find the pages describing what they were running. That matters more than usual for this release: 0.2.0 changes what `replace` means and what an injected `latency` does, so 0.1.0's pages are not merely older, they describe different behaviour. mike keeps one built copy per version on a `gh-pages` branch it owns, alongside the `versions.json` that fills the switcher in the header. The Pages source moves from "GitHub Actions" to that branch, and the workflow drops `pages: write` and `id-token: write` -- nothing talks to the deployment API any more. What gets published now depends on the ref: a push to `main` becomes `dev`, a final tag becomes its bare version number and moves `latest`, and a pre-release tag publishes nothing. The site root redirects to `latest`, so the bare URL lands on the newest release rather than on unreleased documentation. Pre-releases are excluded twice over -- the tag filter and a check in the script -- because `workflow_dispatch` can be pointed at any ref and the filter alone would not stop it. 0.1.0 and 0.2.0 were built and pushed from a checkout of each, so the switcher has both from the start rather than only from the next release onwards. The 0.1.0 build needed `extra.version.provider` added to its `mkdocs.yml` in a throwaway worktree, since that tag predates this commit; the tag itself is untouched and the pages are the ones 0.1.0 shipped.
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.
Automated back-merge of
mainintodevelop.Latest commit on main:
b4a4009-- fix: decide a mock before the faults, and collapse leading slashesOpened by
Back-merge main -> develop, run30796973595.Merge this (or turn on auto-merge) to keep
developin step withmain. Resolve any conflicts here rather than on develop.