[master] 841e8ff0c VCL: Introduce new obj_stale variable
Walid Boudebouda
walid.boudebouda at gmail.com
Mon Sep 1 08:46:05 UTC 2025
commit 841e8ff0c3317f53e231ef24af6711dd20c3b4e8
Author: Walid Boudebouda <walid.boudebouda at gmail.com>
Date: Sat Oct 14 20:07:44 2023 +0200
VCL: Introduce new obj_stale variable
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.
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index edec7d64f..2847e8b87 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -259,6 +259,7 @@ VRT_selecthttp(VRT_CTX, enum gethdr_e where)
case HDR_RESP:
hp = ctx->http_resp;
break;
+ case HDR_OBJ_STALE:
case HDR_OBJ:
hp = NULL;
break;
@@ -283,6 +284,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))
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 7b76b8f35..777f11ad2 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -561,6 +561,7 @@ VRT_r_##obj##_reason(VRT_CTX) \
}
VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore);
+VRT_OC_VAR_R(obj_stale, bo, BUSYOBJ_MAGIC, stale_oc);
/*--------------------------------------------------------------------*/
@@ -800,9 +801,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)
@@ -834,6 +839,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)
/*--------------------------------------------------------------------
*/
@@ -848,6 +854,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)
@@ -1011,6 +1018,28 @@ 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_obj_stale_is_valid(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->flags & OC_F_DYING));
+}
+
+/*--------------------------------------------------------------------*/
+
VCL_BOOL
VRT_r_resp_is_streaming(VRT_CTX)
{
diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst
index 633a2eeb6..627caa15f 100644
--- a/doc/sphinx/reference/vcl_var.rst
+++ b/doc/sphinx/reference/vcl_var.rst
@@ -1429,6 +1429,176 @@ 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_stale.is_valid:
+
+obj_stale.is_valid
+
+ Type: BOOL
+
+ Readable from: vcl_backend_refresh
+
+ Whether the stale object is still valid.
obj
---
diff --git a/include/vrt.h b/include/vrt.h
index 730df304a..188ab693e 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -58,6 +58,19 @@
* binary/load-time compatible, increment MAJOR version
*
* XX.X (unreleased)
+ * 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
* typedef hdr_t added
* struct gethdr_s.what changed to hdr_t
* VRT_VSC_Alloc() renamed to VRT_VSC_Allocv()
@@ -727,7 +740,8 @@ enum gethdr_e {
HDR_RESP,
HDR_OBJ,
HDR_BEREQ,
- HDR_BERESP
+ HDR_BERESP,
+ HDR_OBJ_STALE
};
typedef const struct {
More information about the varnish-commit
mailing list