Skip to content

Commit

Permalink
vcl: Introduce new obj_stale variable
Browse files Browse the repository at this point in the history
obj_stale variable gives access to the stale object we had in cache
when doing a 304 revalidation. It is only readable from vcl_backend_refresh
subroutine.
  • Loading branch information
walid-git committed Oct 16, 2023
1 parent 50107d7 commit 68dda70
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 1 deletion.
9 changes: 9 additions & 0 deletions bin/varnishd/cache/cache_vrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ VRT_selecthttp(VRT_CTX, enum gethdr_e where)
case HDR_RESP:
hp = ctx->http_resp;
break;
case HDR_OBJ_STALE:
/* FALLTHROUGH */
case HDR_OBJ:
hp = NULL;
break;
Expand All @@ -281,6 +283,13 @@ VRT_GetHdr(VRT_CTX, VCL_HEADER hs)
return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
hs->what));
}

if (hs->where == HDR_OBJ_STALE) {
CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
return (HTTP_GetHdrPack(ctx->bo->wrk, ctx->bo->stale_oc,
hs->what));
}
hp = VRT_selecthttp(ctx, hs->where);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
if (!http_GetHdr(hp, hs->what, &p))
Expand Down
19 changes: 19 additions & 0 deletions bin/varnishd/cache/cache_vrt_var.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ VRT_r_##which##_reason(VRT_CTX) \
}

VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore);
VRT_OC_VAR_R(obj_stale, bo, BUSYOBJ_MAGIC, stale_oc);

/*--------------------------------------------------------------------*/

Expand Down Expand Up @@ -774,9 +775,13 @@ VRT_r_##which##_##fld(VRT_CTX) \

/*lint -save -e835 */ // Zero right hand arg to '-'

VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, ttl,
ttl_now(ctx) - ctx->bo->stale_oc->t_origin)
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
ttl_now(ctx) - ctx->req->objcore->t_origin)
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, grace, 0)
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, keep, 0)
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
Expand Down Expand Up @@ -808,6 +813,7 @@ VRT_DO_TIME_R(resp, req, t_resp)
VRT_DO_TIME_R(bereq, bo, t_first)
VRT_DO_TIME_R(beresp, bo, t_resp)
VRT_DO_TIME_R(obj, req->objcore, t_origin)
VRT_DO_TIME_R(obj_stale, bo->stale_oc, t_origin)

/*--------------------------------------------------------------------
*/
Expand All @@ -822,6 +828,7 @@ VRT_r_##which##_##age(VRT_CTX) \
return (ttl_now(ctx) - oc->t_origin); \
}

VRT_DO_AGE_R(obj_stale, ctx->bo->stale_oc)
VRT_DO_AGE_R(obj, ctx->req->objcore)
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)

Expand Down Expand Up @@ -985,6 +992,18 @@ VRT_r_obj_hits(VRT_CTX)

/*--------------------------------------------------------------------*/

VCL_INT
VRT_r_obj_stale_hits(VRT_CTX)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);

return (ctx->bo->stale_oc->hits);
}

/*--------------------------------------------------------------------*/

VCL_BOOL
VRT_r_resp_is_streaming(VRT_CTX)
{
Expand Down
77 changes: 77 additions & 0 deletions bin/varnishtest/tests/b00083.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
varnishtest "Test obj_stale vcl variables"

server s1 {
rxreq
txresp -hdr "Etag: abcd" -hdr "from-bo: true" -bodylen 10
rxreq
expect req.http.if-none-match == "abcd"
txresp -status 304
} -start

varnish v1 -vcl+backend {

sub vcl_backend_response {
set beresp.http.vbresp = "true";
set beresp.ttl = 0.01s;
set beresp.grace = 0s;
set beresp.keep = 10m;
set beresp.http.was-304 = beresp.was_304;
}

sub vcl_backend_refresh {
set beresp.http.vbref = "true";

set beresp.http.http = obj_stale.http.from-bo;
set beresp.http.age = obj_stale.age;
set beresp.http.can_esi = obj_stale.can_esi;
set beresp.http.grace = obj_stale.grace;
set beresp.http.hits = obj_stale.hits;
set beresp.http.keep = obj_stale.keep;
set beresp.http.proto = obj_stale.proto;
set beresp.http.reason = obj_stale.reason;
set beresp.http.status = obj_stale.status;
set beresp.http.storage = obj_stale.storage;
set beresp.http.time = obj_stale.time;
set beresp.http.ttl = obj_stale.ttl;
set beresp.http.uncacheable = obj_stale.uncacheable;

return (merge);
}
} -start

client c1 {
txreq
rxresp
expect resp.status == 200

expect resp.http.was-304 == false
expect resp.http.vbref == <undef>
expect resp.http.vbresp == true
expect resp.http.from-bo == true
} -run

delay 0.01

client c2 {
txreq
rxresp
expect resp.status == 200
expect resp.http.was-304 == true
expect resp.http.vbresp == true
expect resp.http.vbref == true
expect resp.http.from-bo == true

expect resp.http.http == true
expect resp.http.age == 0
expect resp.http.can_esi == false
expect resp.http.grace == 0.000
expect resp.http.hits == 0
expect resp.http.keep == 600.000
expect resp.http.proto == HTTP/1.1
expect resp.http.reason == OK
expect resp.http.status == 200
expect resp.http.storage == storage.s0
expect resp.http.time != <undef>
expect resp.http.ttl != <undef>
expect resp.http.uncacheable == false
} -run
161 changes: 161 additions & 0 deletions doc/sphinx/reference/vcl_var.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,167 @@ beresp.was_304
to our conditional fetch from the backend and turned
that into ``beresp.status = 200``

obj_stale
---------

This is the stale object we had in cache. It cannot be modified.

.. _obj_stale.age:

obj_stale.age

Type: DURATION

Readable from: vcl_backend_refresh

The age of the stale object.


.. _obj_stale.can_esi:

obj_stale.can_esi

Type: BOOL

Readable from: vcl_backend_refresh

If the stale object can be ESI processed, that is if setting
``resp.do_esi`` or adding ``esi`` to ``resp.filters`` in
``vcl_deliver {}`` would cause the response body to be ESI
processed.


.. _obj_stale.grace:

obj_stale.grace

Type: DURATION

Readable from: vcl_backend_refresh

The stale object's grace period in seconds.


.. _obj_stale.hits:

obj_stale.hits

Type: INT

Readable from: vcl_backend_refresh

The count of cache-hits on this stale object.

In `vcl_deliver` a value of 0 indicates a cache miss.


.. _obj_stale.http:

obj_stale.http.*

Type: HEADER

Readable from: vcl_backend_refresh

The HTTP headers stored in the stale object.

See req.http_ for general notes.


.. _obj_stale.keep:

obj_stale.keep

Type: DURATION

Readable from: vcl_backend_refresh

The stale object's keep period in seconds.


.. _obj_stale.proto:

obj_stale.proto

Type: STRING

Readable from: vcl_backend_refresh

The HTTP protocol version stored in the stale object.


.. _obj_stale.reason:

obj_stale.reason

Type: STRING

Readable from: vcl_backend_refresh


The HTTP reason phrase stored in the stale object.


.. _obj_stale.status:

obj_stale.status

Type: INT

Readable from: vcl_backend_refresh


The HTTP status code stored in the stale object.

More information in the `HTTP response status`_ section.


.. _obj_stale.storage:

obj_stale.storage

Type: STEVEDORE

Readable from: vcl_backend_refresh

The storage backend where this stale object is stored.


.. _obj_stale.time:

obj_stale.time

Type: TIME

Readable from: vcl_backend_refresh

The time the stale object was created from the perspective of the
server which generated it. This will roughly be equivalent to
``now`` - ``obj.age``.


.. _obj_stale.ttl:

obj_stale.ttl

Type: DURATION

Readable from: vcl_backend_refresh

The stale object's time to live, in seconds.


.. _obj_stale.uncacheable:

obj_stale.uncacheable

Type: BOOL

Readable from: vcl_backend_refresh

Whether the stale object is uncacheable (pass, hit-for-pass or
hit-for-miss).


obj
---
Expand Down
17 changes: 16 additions & 1 deletion include/vrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@
* Whenever something is deleted or changed in a way which is not
* binary/load-time compatible, increment MAJOR version
*
* NEXT (2024-03-15)
* VRT_r_obj_stale_age() added
* VRT_r_obj_stale_can_esi() added
* VRT_r_obj_stale_grace() added
* VRT_r_obj_stale_hits() added
* VRT_r_obj_stale_keep() added
* VRT_r_obj_stale_proto() added
* VRT_r_obj_stale_reason() added
* VRT_r_obj_stale_status() added
* VRT_r_obj_stale_storage() added
* VRT_r_obj_stale_time() added
* VRT_r_obj_stale_ttl() added
* VRT_r_obj_stale_uncacheable() added
* enum gethdr_e has new value HDR_OBJ_STALE
* 18.0 (2023-09-15)
* [cache_filter.h] struct vdp gained priv1 member
* VRT_trace() added
Expand Down Expand Up @@ -640,7 +654,8 @@ enum gethdr_e {
HDR_RESP,
HDR_OBJ,
HDR_BEREQ,
HDR_BERESP
HDR_BERESP,
HDR_OBJ_STALE
};

struct gethdr_s {
Expand Down

0 comments on commit 68dda70

Please sign in to comment.