Skip to content

vcl: Make 'none' a reserved keyword and use it for probes #4309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

dridi
Copy link
Member

@dridi dridi commented Apr 7, 2025

⚠️ This is technically a VCL BREAKING CHANGE but we should make it. ⚠️

This patch series does several things, but the effective goal is to enable this:

backend improbable {
        .host = "legacy.example.com";
        .probe = none;
}

Having backends we can't probe also prevents the use of a default probe, so my suggestion here is to allow none as a special value for the .probe field in backend definitions.

This is a breaking change, but I believe we should treat it as a bug fix and proceed without concern for broken VCL. In exchange, it should of course be one of the headlines in the release notes.

Once none becomes a reserved word, we can imagine solving the recurring confusion around unset values:

We could imagine the two if statements becoming equivalent:

if (req.http.foo) { }
if (req.http.foo != none) { }

In the ⚠️ ACTUALLY BREAKING ⚠️ department, some would like to change the behavior of set HEADER = HEADER;:

unset req.http.missing;
set req.http.assigned = req.http.missing;
# expect both headers to be 'none' here

I personally think it's an interesting question that should extend to set HEADER = STRING; for null strings. For comparisons in general, it could apply to any expression that can yield a null pointer. Something to consider for the next revision of VCL.

This pull requests stops after turning none into the keyword it should have become on day one, in hindsight, and then uses this keyword to explicitly circumvent the default probe.

dridi added 5 commits April 7, 2025 11:48
Getting "Name default must have type 'func'" is very confusing.
This is a breaking change, and alternatively, a new VCL 4.2 syntax could
treat it as a keyword while still retaining the current semantics with
VCL <= 4.1, but I think we should simply bite this bullet. Having it
both as a possible symbol name and a special keyword is sufficient to
justify this breakage.

Case in point, all the test cases affected by this change, showing usage
of 'none' as both a symbol name and a keyword:

    backend none none;

In general, reserving this keyword could be a solution to clarify VCL.
In the future, these two blocks could become identical:

    if (req.http.unsure) { }
    if (req.http.unsure != none) { }

That would solve a long-standing confusion regarding header presence in
a message. Another actionable change this promotion to a reserved word
is leading to is the ability to ignore the default probe in a backend
definition.
This allows VMODs to create a backend without a probe, regardless of the
presence of a default probe.
VCL authors can define a default probe for all backends without their
own probe definitions. Until now, a backend could override the default
probe with a different probe configuration. From now on, a backend can
opt out of the default probe.
@nigoroll
Copy link
Member

nigoroll commented Apr 9, 2025

So this looks very sensible to me.

Just one question: Is it really the best option to keep NULL for "default probe", or should NULL become "no probe" and instead introduce a magic value for "default probe"?

@dridi
Copy link
Member Author

dridi commented Apr 14, 2025

Just one question: Is it really the best option to keep NULL for "default probe", or should NULL become "no probe" and instead introduce a magic value for "default probe"?

This is what I tried first, but that magic value would live in varnishd and not be considered constant enough to appear in static initializers. Following this path would have broken the API, which I tried to preserve.

Copy link
Member

@nigoroll nigoroll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with the VRT argument, but noticed one important aspect during a second review round

@@ -142,7 +142,7 @@ varnish v1 -errvcl {Symbol not found: 'obj'} {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the commit message:
As with other versioning questions, I think we should only increase the major version for silent breaking changes. In this case a VCL compilation failure ensures that VCL authors become aware of the change, so we do not need a VCL version bump.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I think we should consider it a bug fix, we should never have authorized none to persist as a usable symbol name once we gave it a special meaning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

}
backend s0 {
.host = "${s0_sock}";
.probe = none;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also make sure please that this also works for a VCL_PROBE vmod function/method argument?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can pass none for a backends either, that would be a subsequent change (among a couple others) should this one be approved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always define a none backend and then pass that, so that is not so important. For probes we don't have that option.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so you'd like to align this change with backend definitions?

probe disabled none;

backend improbable {
       .probe = none;
}

backend also_improbable {
       .probe = disabled;
}

That would increase overall consistency, good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants