https://github.com/varnishcache/varnish-cache/issues/1874 somehow caught my attention because years ago I made an attempt to suggest that we should use the monotonic clock almost always.
So here's a suggestion for a simple interface which would allow us to still use wallclock time, but make it partially monotonic based on a timestamp: VTIM_ts_now() calculates a new wallclock time based on the monotonic clock delta. I think there are some other places where we could just use monotonic timestamps, but for the remaining timestamps this suggestion could be an option. Nils
>From 097fd11da76807784f660ccd17f2174a71b5f796 Mon Sep 17 00:00:00 2001 From: Nils Goroll <[email protected]> Date: Thu, 31 Mar 2016 18:16:11 +0200 Subject: [PATCH] Add a simple interface to make wallclock time monotonic --- bin/varnishd/cache/cache.h | 3 +- bin/varnishd/cache/cache_acceptor.c | 7 ++--- bin/varnishd/cache/cache_backend.c | 1 - bin/varnishd/cache/cache_backend_cfg.c | 1 - bin/varnishd/cache/cache_backend_probe.c | 1 - bin/varnishd/cache/cache_backend_tcp.c | 1 - bin/varnishd/cache/cache_ban_build.c | 1 - bin/varnishd/cache/cache_ban_lurker.c | 1 - bin/varnishd/cache/cache_esi_deliver.c | 1 - bin/varnishd/cache/cache_expire.c | 1 - bin/varnishd/cache/cache_fetch.c | 1 - bin/varnishd/cache/cache_hash.c | 1 - bin/varnishd/cache/cache_http.c | 1 - bin/varnishd/cache/cache_mempool.c | 2 -- bin/varnishd/cache/cache_panic.c | 3 +- bin/varnishd/cache/cache_req.c | 2 -- bin/varnishd/cache/cache_req_body.c | 1 - bin/varnishd/cache/cache_req_fsm.c | 1 - bin/varnishd/cache/cache_rfc2616.c | 2 -- bin/varnishd/cache/cache_session.c | 11 ++++---- bin/varnishd/cache/cache_shmlog.c | 1 - bin/varnishd/cache/cache_vrt.c | 1 - bin/varnishd/cache/cache_wrk.c | 2 -- bin/varnishd/hash/hash_critbit.c | 1 - bin/varnishd/http1/cache_http1_fetch.c | 1 - bin/varnishd/http1/cache_http1_line.c | 1 - bin/varnishd/storage/storage_persistent.c | 1 - bin/varnishd/storage/storage_persistent_silo.c | 1 - bin/varnishd/waiter/cache_waiter_epoll.c | 1 - bin/varnishd/waiter/cache_waiter_kqueue.c | 1 - bin/varnishd/waiter/cache_waiter_poll.c | 1 - bin/varnishd/waiter/cache_waiter_ports.c | 1 - include/vtim.h | 38 ++++++++++++++++++++++++++ lib/libvarnish/vtim.c | 33 ++++++++++++++++++++++ lib/libvmod_debug/vmod_debug.c | 1 - lib/libvmod_std/vmod_std.c | 1 - lib/libvmod_std/vmod_std_conversions.c | 1 - 37 files changed, 83 insertions(+), 47 deletions(-) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 44f1c81..0de04f5 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -53,6 +53,7 @@ #include <limits.h> #include <unistd.h> #include <math.h> +#include <vtim.h> #include "common/params.h" @@ -646,7 +647,7 @@ struct sess { struct ws ws[1]; /* Timestamps, all on TIM_real() timescale */ - double t_open; /* fd accepted */ + struct vtim_ts t_open; /* fd accepted */ double t_idle; /* fd accepted or resp sent */ struct vrt_privs privs[1]; diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 42fd3f0..f7b7c14 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -49,7 +49,6 @@ #include "vcli_priv.h" #include "vsa.h" #include "vtcp.h" -#include "vtim.h" static pthread_t VCA_thread; static double vca_pace = 0.0; @@ -332,8 +331,8 @@ vca_make_session(struct worker *wrk, void *arg) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk->stats->s_sess++; - sp->t_open = VTIM_real(); - sp->t_idle = sp->t_open; + VTIM_ts_set(&sp->t_open); + sp->t_idle = VTIM_ts_real(&sp->t_open); sp->vxid = VXID_Get(wrk, VSL_CLIENTMARKER); sp->fd = wa->acceptsock; @@ -360,7 +359,7 @@ vca_make_session(struct worker *wrk, void *arg) wa->acceptlsock->transport->name); VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f %d", raddr, rport, wa->acceptlsock->name, laddr, lport, - sp->t_open, sp->fd); + VTIM_ts_real(&sp->t_open), sp->fd); WS_Release(wrk->aws, 0); diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 2fff7c2..94d4d4a 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -38,7 +38,6 @@ #include "vrt.h" #include "vtcp.h" -#include "vtim.h" #include "cache_director.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c index a1ae800..dcac6ac 100644 --- a/bin/varnishd/cache/cache_backend_cfg.c +++ b/bin/varnishd/cache/cache_backend_cfg.c @@ -42,7 +42,6 @@ #include "vcli.h" #include "vcli_priv.h" #include "vrt.h" -#include "vtim.h" #include "cache_director.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index ea63abe..a9009fd 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -48,7 +48,6 @@ #include "vrt.h" #include "vsa.h" #include "vtcp.h" -#include "vtim.h" #include "cache_director.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache/cache_backend_tcp.c b/bin/varnishd/cache/cache_backend_tcp.c index fdabe6f..11a684b 100644 --- a/bin/varnishd/cache/cache_backend_tcp.c +++ b/bin/varnishd/cache/cache_backend_tcp.c @@ -41,7 +41,6 @@ #include "vrt.h" #include "vsa.h" #include "vtcp.h" -#include "vtim.h" #include "cache_director.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache/cache_ban_build.c b/bin/varnishd/cache/cache_ban_build.c index 55c78ae..39fa89a 100644 --- a/bin/varnishd/cache/cache_ban_build.c +++ b/bin/varnishd/cache/cache_ban_build.c @@ -36,7 +36,6 @@ #include "cache_ban.h" #include "vend.h" -#include "vtim.h" struct ban_proto { unsigned magic; diff --git a/bin/varnishd/cache/cache_ban_lurker.c b/bin/varnishd/cache/cache_ban_lurker.c index 65c552e..fbe7521 100644 --- a/bin/varnishd/cache/cache_ban_lurker.c +++ b/bin/varnishd/cache/cache_ban_lurker.c @@ -34,7 +34,6 @@ #include "cache_ban.h" #include "hash/hash_slinger.h" -#include "vtim.h" static struct objcore oc_marker = { .magic = OBJCORE_MAGIC, }; static unsigned ban_batch; diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index ecb01bc..f5511b9 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -37,7 +37,6 @@ #include "cache_transport.h" #include "cache_filter.h" -#include "vtim.h" #include "cache_esi.h" #include "vend.h" #include "vgz.h" diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c index a6c2d3f..6af9c7f 100644 --- a/bin/varnishd/cache/cache_expire.c +++ b/bin/varnishd/cache/cache_expire.c @@ -38,7 +38,6 @@ #include "binary_heap.h" #include "hash/hash_slinger.h" -#include "vtim.h" struct exp_priv { unsigned magic; diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index fb7c638..06eab67 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -34,7 +34,6 @@ #include "cache_filter.h" #include "hash/hash_slinger.h" #include "vcl.h" -#include "vtim.h" /*-------------------------------------------------------------------- * Allocate an object, with fall-back to Transient. diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index fc5c368..b63d947 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -60,7 +60,6 @@ #include "hash/hash_slinger.h" #include "vsha256.h" -#include "vtim.h" static const struct hash_slinger *hash; static struct objhead *private_oh; diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 2cdb28c..72689e9 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -38,7 +38,6 @@ #include "vend.h" #include "vct.h" -#include "vtim.h" #define HTTPH(a, b, c) char b[] = "*" a ":"; #include "tbl/http_headers.h" diff --git a/bin/varnishd/cache/cache_mempool.c b/bin/varnishd/cache/cache_mempool.c index 85ca62c..a734c6c 100644 --- a/bin/varnishd/cache/cache_mempool.c +++ b/bin/varnishd/cache/cache_mempool.c @@ -35,8 +35,6 @@ #include "cache.h" -#include "vtim.h" - struct memitem { unsigned magic; #define MEMITEM_MAGIC 0x42e55401 diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index e0c5268..fda68a0 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -470,7 +470,8 @@ pan_sess(struct vsb *vsb, const struct sess *sp) xp = XPORT_ByNumber(sp->sattr[SA_TRANSPORT]); VSB_printf(vsb, "fd = %d, vxid = %u,\n", sp->fd, VXID(sp->vxid)); - VSB_printf(vsb, "t_open = %f,\n", sp->t_open); + VSB_printf(vsb, "t_open = {%f, %f},\n", + VTIM_ts_mono(&sp->t_open), VTIM_ts_real(&sp->t_open)); VSB_printf(vsb, "t_idle = %f,\n", sp->t_idle); VSB_printf(vsb, "transport = %s", xp == NULL ? "<none>" : xp->name); diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index f4e4f61..31a7d06 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -40,8 +40,6 @@ #include "cache.h" #include "cache_pool.h" -#include "vtim.h" - /*-------------------------------------------------------------------- * Alloc/Free a request */ diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c index ec57a42..d376944 100644 --- a/bin/varnishd/cache/cache_req_body.c +++ b/bin/varnishd/cache/cache_req_body.c @@ -34,7 +34,6 @@ #include "cache.h" #include "cache_filter.h" -#include "vtim.h" #include "hash/hash_slinger.h" /*---------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 333083e..6ee37d5 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -46,7 +46,6 @@ #include "hash/hash_slinger.h" #include "vcl.h" #include "vsha256.h" -#include "vtim.h" /*-------------------------------------------------------------------- * Deliver an object to client diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c index 6b80371..7507a05 100644 --- a/bin/varnishd/cache/cache_rfc2616.c +++ b/bin/varnishd/cache/cache_rfc2616.c @@ -33,8 +33,6 @@ #include "cache.h" -#include "vtim.h" - /*-------------------------------------------------------------------- * TTL and Age calculation in Varnish * diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 4208fc5..85bb370 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -46,7 +46,6 @@ #include "vsa.h" #include "vtcp.h" -#include "vtim.h" /*--------------------------------------------------------------------*/ @@ -331,7 +330,7 @@ SES_New(struct pool *pp) assert(p < e); WS_Init(sp->ws, "ses", p, e - p); - sp->t_open = NAN; + VTIM_ts_invalidate(&sp->t_open); sp->t_idle = NAN; VRTPRIV_init(sp->privs); Lck_New(&sp->mtx, lck_sess); @@ -515,16 +514,16 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) assert(sp->fd < 0); if (isnan(now)) - now = VTIM_real(); - AZ(isnan(sp->t_open)); + now = VTIM_ts_now(&sp->t_open); + assert(VTIM_ts_valid(&sp->t_open)); if (reason == SC_NULL) reason = (enum sess_close)-sp->fd; - assert(now >= sp->t_open); + assert(now >= VTIM_ts_real(&sp->t_open)); assert(VTAILQ_EMPTY(&sp->privs->privs)); VSL(SLT_SessClose, sp->vxid, "%s %.3f", - sess_close_2str(reason, 0), now - sp->t_open); + sess_close_2str(reason, 0), VTIM_ts_age(&sp->t_open)); VSL(SLT_End, sp->vxid, "%s", ""); Lck_Delete(&sp->mtx); diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index e733686..eadc75b 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -38,7 +38,6 @@ #include "vsl_priv.h" #include "vmb.h" -#include "vtim.h" /* These cannot be struct lock, which depends on vsm/vsl working */ static pthread_mutex_t vsl_mtx; diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index a82b1e4..18dccaf 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -41,7 +41,6 @@ #include "vrt_obj.h" #include "vsa.h" #include "vtcp.h" -#include "vtim.h" const void * const vrt_magic_string_end = &vrt_magic_string_end; const void * const vrt_magic_string_unset = &vrt_magic_string_unset; diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 7176f09..3875f65 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -37,8 +37,6 @@ #include "cache.h" #include "cache_pool.h" -#include "vtim.h" - #include "hash/hash_slinger.h" static void Pool_Work_Thread(struct pool *pp, struct worker *wrk); diff --git a/bin/varnishd/hash/hash_critbit.c b/bin/varnishd/hash/hash_critbit.c index 4b9cc6b..61ef19e 100644 --- a/bin/varnishd/hash/hash_critbit.c +++ b/bin/varnishd/hash/hash_critbit.c @@ -39,7 +39,6 @@ #include "hash/hash_slinger.h" #include "vcli_priv.h" #include "vmb.h" -#include "vtim.h" static struct lock hcb_mtx; diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index ef24a71..2fd84c5 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -38,7 +38,6 @@ #include "vcli_priv.h" #include "vrt.h" #include "vtcp.h" -#include "vtim.h" #include "hash/hash_slinger.h" diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c index 9f13543..645aa5c 100644 --- a/bin/varnishd/http1/cache_http1_line.c +++ b/bin/varnishd/http1/cache_http1_line.c @@ -42,7 +42,6 @@ #include "cache/cache.h" #include "cache_http1.h" -#include "vtim.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index d52c2cc..f550a7c 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -51,7 +51,6 @@ #include "vcli.h" #include "vcli_priv.h" #include "vsha256.h" -#include "vtim.h" #include "storage/storage_persistent.h" diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c index 61ae93b..7d3cd64 100644 --- a/bin/varnishd/storage/storage_persistent_silo.c +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -46,7 +46,6 @@ #include "hash/hash_slinger.h" #include "vsha256.h" #include "vend.h" -#include "vtim.h" #include "storage/storage_persistent.h" diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c index f50ae46..e9ab9e4 100644 --- a/bin/varnishd/waiter/cache_waiter_epoll.c +++ b/bin/varnishd/waiter/cache_waiter_epoll.c @@ -44,7 +44,6 @@ #include "waiter/waiter_priv.h" #include "waiter/mgt_waiter.h" -#include "vtim.h" #include "vfil.h" #ifndef EPOLLRDHUP diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c index 02d7adc..ec83530 100644 --- a/bin/varnishd/waiter/cache_waiter_kqueue.c +++ b/bin/varnishd/waiter/cache_waiter_kqueue.c @@ -42,7 +42,6 @@ #include "waiter/waiter_priv.h" #include "waiter/mgt_waiter.h" -#include "vtim.h" #define NKEV 256 diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c index 5e2edb8..0d3fcd3 100644 --- a/bin/varnishd/waiter/cache_waiter_poll.c +++ b/bin/varnishd/waiter/cache_waiter_poll.c @@ -38,7 +38,6 @@ #include "waiter/waiter_priv.h" #include "waiter/mgt_waiter.h" -#include "vtim.h" struct vwp { unsigned magic; diff --git a/bin/varnishd/waiter/cache_waiter_ports.c b/bin/varnishd/waiter/cache_waiter_ports.c index 49c6790..05e78cd 100644 --- a/bin/varnishd/waiter/cache_waiter_ports.c +++ b/bin/varnishd/waiter/cache_waiter_ports.c @@ -76,7 +76,6 @@ #include "waiter/waiter_priv.h" #include "waiter/mgt_waiter.h" -#include "vtim.h" // XXX replace with process.max-port-events bound to a sensible maximum #define MAX_EVENTS 256 diff --git a/include/vtim.h b/include/vtim.h index 8db4fbe..8c282fe 100644 --- a/include/vtim.h +++ b/include/vtim.h @@ -28,12 +28,50 @@ * */ +#include <math.h> + +struct vtim_ts { + double mono; + double real; +}; + +static inline double +VTIM_ts_mono(const struct vtim_ts *ts) +{ + return (ts->mono); +} + +static inline double +VTIM_ts_real(const struct vtim_ts *ts) +{ + return (ts->real); +} + +static inline void +VTIM_ts_invalidate(struct vtim_ts *ts) +{ + ts->real = NAN; + ts->mono = NAN; +} + +static inline int +VTIM_ts_valid(const struct vtim_ts *ts) +{ + return ( + ts->real != NAN && ts->mono != NAN && + ts->real > 0.0 && ts->mono > 0.0 + ); +} + /* from libvarnish/vtim.c */ #define VTIM_FORMAT_SIZE 30 void VTIM_format(double t, char *p); double VTIM_parse(const char *p); double VTIM_mono(void); double VTIM_real(void); +void VTIM_ts_set(struct vtim_ts *ts); +double VTIM_ts_now(const struct vtim_ts *ts); +double VTIM_ts_age(const struct vtim_ts *ts); void VTIM_sleep(double t); struct timespec VTIM_timespec(double t); struct timeval VTIM_timeval(double t); diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c index 509ba9a..64699a1 100644 --- a/lib/libvarnish/vtim.c +++ b/lib/libvarnish/vtim.c @@ -127,6 +127,39 @@ VTIM_real(void) #endif } +/* + * vtim_ts saves both the mono and real timestamp, which allows to retrieve a + * monotonically increating real time (ie guarantted not to step) based on the + * mono time difference. + * + * VTIM_mono() is more efficient than VTIM_real() on some Platforms, so + * VTIM_ts_now() may also be more efficient than VTIM_real() + */ + +/* not mp-safe */ +void +VTIM_ts_set(struct vtim_ts *ts) +{ + ts->real = VTIM_real(); + ts->mono = VTIM_mono(); +} + +double +VTIM_ts_now(const struct vtim_ts *ts) +{ + assert(VTIM_ts_valid(ts)); + + return (ts->real + VTIM_mono() - ts->mono); +} + +double +VTIM_ts_age(const struct vtim_ts *ts) +{ + assert(VTIM_ts_valid(ts)); + + return (VTIM_mono() - ts->mono); +} + void VTIM_format(double t, char *p) { diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index e00332b..580a326 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -40,7 +40,6 @@ #include "vsa.h" #include "vsb.h" #include "vtcp.h" -#include "vtim.h" #include "vcc_if.h" struct priv_vcl { diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 1a8f56b..4cc2515 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -40,7 +40,6 @@ #include "vrt.h" #include "vtcp.h" #include "vsa.h" -#include "vtim.h" #include "cache/cache.h" #include "cache/cache_director.h" diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c index 1506ec9..2025739 100644 --- a/lib/libvmod_std/vmod_std_conversions.c +++ b/lib/libvmod_std/vmod_std_conversions.c @@ -42,7 +42,6 @@ #include "vnum.h" #include "vrt.h" #include "vsa.h" -#include "vtim.h" #include "vcc_if.h" VCL_DURATION __match_proto__(td_std_duration) -- 2.1.4
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
