refactor: let a variable read the kind of the member it was given - #400
Merged
Merged
Conversation
The table says of every member whether it is a counter or a queue, and the two are read differently. The variables were handed the offset and not the kind, so the one that has to average a queue recognised itself by comparing its offset against stat_request_times - the only queue a variable has ever named. The knowledge that a field is a queue sat in two places, and the copy in variables.c named a single field. Hand the row instead of the offset, and ask it. The offset is still what the value is read at, so nothing moves: of the eighteen members a variable can read, one is a queue and it is that one, and every one of the eighteen takes the branch it took before. While here, say why responseMsecCounter and responseMsec are the two members no variable reads, which the table did not. A variable is answered from the server zone of the request, and the upstream times are written to the node of the peer that served it, in shm.c. On a server zone they are the zeroes the node was created with, so a variable named here would report 0 for every request, for ever, with nothing to say it was wrong - before this change and after it alike, since a zeroed queue averages to zero. set_by_filter names them because it is told which zone to read, and can be told an upstream one.
u5surf
force-pushed
the
fix/variables-member-kind
branch
from
September 12, 2026 07:24
a4a9822 to
b6b549a
Compare
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.
What this changes
The members table added in #395 says of every member whether it is a counter
or a queue, and the two are read differently. The variables are handed the
offset and not the kind, so the handler that has to average a queue recognises
itself by comparing its offset against
stat_request_times— the only queue avariable has ever named:
So the knowledge that a field is a queue lives in two places, and the copy in
variables.cnames one particular field. This hands the row instead of theoffset and asks it, which is what
set.calready does for the same two kinds.A second commit writes down why
responseMsecCounterandresponseMsecarethe two members no variable reads, which the table did not say.
This fixes no bug. Nothing behaves differently and nothing new becomes
possible; it is the implicit coupling that goes away. If that is not worth a
change here, I am happy to close it.
What it does not do
I originally expected this to be what stands between the
responseMsecrow anda variable. It is not — there are two reasons that row has none, and this
addresses one:
stat_request_timesis averagedshm.c. On a server zone they are the zeroes the node was created withAdding
vts_response_timeto that row on this branch still reports 0 for everyrequest.
set_by_filtercan name those members because it is told which zoneto read and can be told an upstream one. The second commit records this at the
rows themselves, so the next person does not have to find it out.
How it was verified
Built from a clean tree on
a8e0215, nginx 1.31.6,-Wall -Wextraclean withNGX_HTTP_CACHEon and off.Behaviour is unchanged by construction, not only by the suite. Comparing the
old test (offset equals
stat_request_times) with the new one (kind isQUEUE) over every row that carries a variable:Of the eighteen, one is a queue and it is
vts_request_time.Separately, I checked what the old code did when the
responseMsecrow wasgiven a variable — a 50 ms backend, five proxied requests, then both queue
variables read from the same server zone:
That 0 is reason 2 above, and it is the same on this branch. It is why the
comment is worth more here than the code is.
Checklist
--without-http-cacheas well as with the cache enabled.ngx_http_vhost_traffic_status_node_tis untouched and
sizeof()is unchanged.nginx_versionguard — not applicable, no nginx field or function is newly used...._FMT_...macro is touched.t/— not applicable, there is no behaviour to test. Theequivalence is argued above instead.
README.md/CHANGELOG.md— not applicable, nothing here is visible to users.Assistance Disclosure
AI used. I asked Claude to make the handler read the kind from the table rather
than infer it from the offset; it wrote the change, built it, ran the tests, and
ran the branch-equivalence check and the two-variable experiment above. I
reviewed the result. The finding that reason 2 exists — and so that this change
does not do what I first thought it would — came out of that experiment rather
than from reading the code.