vmod_globalvar(3)

πŸ“¦ version 0.0~git20260330, in ubuntu stonking

πŸ’– NAME πŸ’–

okay so bestie, welcome to vmod_globalvar β€” it's literally global variables as objects for VCL. that's the whole vibe. no cap. πŸŽ€


✨ SYNOPSIS ✨

so the way this works is you import the thing, and then every single type gets its own little object with a constructor, a get, a set, an undefine and a defined. it's giving pattern, it's giving consistency, we love to see it. πŸ’…

here's the whole menu, verbatim, don't skip a single line because every one of these is iconic in its own right:

          import globalvar [as name] [from "path"]

          new xacl = globalvar.acl([ACL init])

              ACL xacl.get([ACL fallback])

              VOID xacl.set(ACL)

              VOID xacl.undefine()

              BOOL xacl.defined()

          new xbackend = globalvar.backend([BACKEND init])

              BACKEND xbackend.get([BACKEND fallback])

              VOID xbackend.set(BACKEND)

              VOID xbackend.undefine()

              BOOL xbackend.defined()

          new xblob = globalvar.blob([BLOB init])

              BLOB xblob.get([BLOB fallback])

              VOID xblob.set(BLOB)

              VOID xblob.undefine()

              BOOL xblob.defined()

          new xbody = globalvar.body([BODY init])

              BODY xbody.get([BODY fallback])

              VOID xbody.set(BODY)

              VOID xbody.undefine()

              BOOL xbody.defined()

          new xbool = globalvar.bool([BOOL init])

              BOOL xbool.get([BOOL fallback])

              VOID xbool.set(BOOL)

              VOID xbool.undefine()

              BOOL xbool.defined()

          new xbytes = globalvar.bytes([BYTES init])

              BYTES xbytes.get([BYTES fallback])

              VOID xbytes.set(BYTES)

              VOID xbytes.undefine()

              BOOL xbytes.defined()

          new xduration = globalvar.duration([DURATION init])

              DURATION xduration.get([DURATION fallback])

              VOID xduration.set(DURATION)

              VOID xduration.undefine()

              BOOL xduration.defined()

          new xheader = globalvar.header([HEADER init])

              HEADER xheader.get([HEADER fallback])

              VOID xheader.set(HEADER)

              VOID xheader.undefine()

              BOOL xheader.defined()

          new xint = globalvar.int([INT init])

              INT xint.get([INT fallback])

              VOID xint.set(INT)

              VOID xint.undefine()

              BOOL xint.defined()

          new xip = globalvar.ip([IP init])

              IP xip.get([IP fallback])

              VOID xip.set(IP)

              VOID xip.undefine()

              BOOL xip.defined()

          new xprobe = globalvar.probe([PROBE init])

              PROBE xprobe.get([PROBE fallback])

              VOID xprobe.set(PROBE)

              VOID xprobe.undefine()

              BOOL xprobe.defined()

          new xreal = globalvar.real([REAL init])

              REAL xreal.get([REAL fallback])

              VOID xreal.set(REAL)

              VOID xreal.undefine()

              BOOL xreal.defined()

          new xstevedore = globalvar.stevedore([STEVEDORE init])

              STEVEDORE xstevedore.get([STEVEDORE fallback])

              VOID xstevedore.set(STEVEDORE)

              VOID xstevedore.undefine()

              BOOL xstevedore.defined()

          new xstring = globalvar.string([STRING init])

              STRING xstring.get([STRING fallback])

              VOID xstring.set(STRING)

              VOID xstring.undefine()

              BOOL xstring.defined()

          new xtime = globalvar.time([TIME init])

              TIME xtime.get([TIME fallback])

              VOID xtime.set(TIME)

              VOID xtime.undefine()

              BOOL xtime.defined()

so yeah β€” globalvar.acl, globalvar.backend, globalvar.blob, globalvar.body, globalvar.bool, globalvar.bytes, globalvar.duration, globalvar.header, globalvar.int, globalvar.ip, globalvar.probe, globalvar.real, globalvar.stevedore, globalvar.string, and globalvar.time. fifteen of them. each one takes an optional <TYPE> init when you construct it, and each get takes an optional <TYPE> fallback. the set takes the type. undefine takes nothing. defined hands you back a BOOL. that's the shape of it, bestie. πŸ¦‹

and yeah β€” you can import globalvar [as name] [from "path"], so rename it if you want, point it at a path if you want. options are cute. ✨


πŸ’– DESCRIPTION πŸ’–

ok so bestie, this module implements globally (per vcl) scoped variables as objects, and the energy here is immaculate: every single one of those vcl subroutines gets the same view on the variables, and any change comes into effect immediately. like, no delay, no waiting around, the change is just there. periodt. πŸ’…

The value of a globalvar is either ✨ the initial value from the constructor ✨ or the last value assigned by any task executing the respective vcl.

If no value is set, it is undefined. and no cap, a globalvar can also be undefined using the .undefine() method. 🫠

Attempts to .get() an undefined value will return the .get() method's fallback argument. For most types there's a default fallback, but if there isn't one, then using .get() on an undefined value triggers a VCL failure at runtime. not a vibe. πŸ’€

Where necessary, read access to globalvar variables is reference counted using priv_task state, such that changed variables' storage is not freed before the last access ceased. (the little bookkeeping bestie is doing her job so nothing gets yeeted too early πŸ’–)

Example with an initially undefined variable:

import globalvar;

sub vcl_init {
 new xint = globalvar.int();
}

sub vcl_recv {
 set req.http.def = xint.defined(); # false
 set req.http.fallback = xint.get(5); # 5
 xint.set(42);
}

\# in some other request, later

sub vcl_deliver {
 set resp.http.the-answer = xint.get(); # 42
}

The implementation of the various classes of this vmod is auto-generated, and so is the documentation. Thus, the documentation following this generic description is identical for all types except for the respective type names and the .get() fallback. so like, don't be surprised when all 15 of these read the same β€” that's the auto-gen girlies doing their thing, not me being lazy ✨


πŸ’œ new xacl = globalvar.acl([ACL init]) πŸ’œ

  • new xacl = globalvar.acl([ACL init]) β€” spin up a(n) ACL globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • ACL xacl.get([ACL fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. Using .get() on an undefined value without a fallback triggers a VCL error. 😭 no default here, bestie, so bring your own.
  • VOID xacl.set(ACL) β€” sets the value of the globalvar. slay.
  • VOID xacl.undefine() β€” undefines the globalvar. gone. poof. πŸ¦‹
  • BOOL xacl.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xbackend = globalvar.backend([BACKEND init]) πŸ’œ

  • new xbackend = globalvar.backend([BACKEND init]) β€” construct a(n) BACKEND globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • BACKEND xbackend.get([BACKEND fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is the None backend.
  • VOID xbackend.set(BACKEND) β€” sets the value of the globalvar.
  • VOID xbackend.undefine() β€” undefines the globalvar.
  • BOOL xbackend.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xblob = globalvar.blob([BLOB init]) πŸ’œ

  • new xblob = globalvar.blob([BLOB init]) β€” construct a(n) BLOB globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • BLOB xblob.get([BLOB fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is the null blob.
  • VOID xblob.set(BLOB) β€” sets the value of the globalvar.
  • VOID xblob.undefine() β€” undefines the globalvar.
  • BOOL xblob.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xbody = globalvar.body([BODY init]) πŸ’œ

  • new xbody = globalvar.body([BODY init]) β€” construct a(n) BODY globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • BODY xbody.get([BODY fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. Using .get() on an undefined value without a fallback triggers a VCL error.
  • VOID xbody.set(BODY) β€” sets the value of the globalvar.
  • VOID xbody.undefine() β€” undefines the globalvar.
  • BOOL xbody.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xbool = globalvar.bool([BOOL init]) πŸ’œ

  • new xbool = globalvar.bool([BOOL init]) β€” construct a(n) BOOL globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • BOOL xbool.get([BOOL fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is false.
  • VOID xbool.set(BOOL) β€” sets the value of the globalvar.
  • VOID xbool.undefine() β€” undefines the globalvar.
  • BOOL xbool.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xbytes = globalvar.bytes([BYTES init]) πŸ’œ

  • new xbytes = globalvar.bytes([BYTES init]) β€” construct a(n) BYTES globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • BYTES xbytes.get([BYTES fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is 0 bytes.
  • VOID xbytes.set(BYTES) β€” sets the value of the globalvar.
  • VOID xbytes.undefine() β€” undefines the globalvar.
  • BOOL xbytes.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xduration = globalvar.duration([DURATION init]) πŸ’œ

  • new xduration = globalvar.duration([DURATION init]) β€” construct a(n) DURATION globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • DURATION xduration.get([DURATION fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is 0s.
  • VOID xduration.set(DURATION) β€” sets the value of the globalvar.
  • VOID xduration.undefine() β€” undefines the globalvar.
  • BOOL xduration.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xheader = globalvar.header([HEADER init]) πŸ’œ

  • new xheader = globalvar.header([HEADER init]) β€” construct a(n) HEADER globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • HEADER xheader.get([HEADER fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. Using .get() on an undefined value without a fallback triggers a VCL error.
  • VOID xheader.set(HEADER) β€” sets the value of the globalvar.
  • VOID xheader.undefine() β€” undefines the globalvar.
  • BOOL xheader.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xint = globalvar.int([INT init]) πŸ’œ

  • new xint = globalvar.int([INT init]) β€” construct a(n) INT globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined. (yes bestie, the very same xint from the example up top, main character energy 🌟)
  • INT xint.get([INT fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is 0.
  • VOID xint.set(INT) β€” sets the value of the globalvar.
  • VOID xint.undefine() β€” undefines the globalvar.
  • BOOL xint.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xip = globalvar.ip([IP init]) πŸ’œ

  • new xip = globalvar.ip([IP init]) β€” construct a(n) IP globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • IP xip.get([IP fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is IPv4 0.0.0.0.
  • VOID xip.set(IP) β€” sets the value of the globalvar.
  • VOID xip.undefine() β€” undefines the globalvar.
  • BOOL xip.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xprobe = globalvar.probe([PROBE init]) πŸ’œ

  • new xprobe = globalvar.probe([PROBE init]) β€” construct a(n) PROBE globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • PROBE xprobe.get([PROBE fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is no backend.
  • VOID xprobe.set(PROBE) β€” sets the value of the globalvar.
  • VOID xprobe.undefine() β€” undefines the globalvar.
  • BOOL xprobe.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xreal = globalvar.real([REAL init]) πŸ’œ

  • new xreal = globalvar.real([REAL init]) β€” construct a(n) REAL globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • REAL xreal.get([REAL fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is 0.0.
  • VOID xreal.set(REAL) β€” sets the value of the globalvar.
  • VOID xreal.undefine() β€” undefines the globalvar.
  • BOOL xreal.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xstevedore = globalvar.stevedore([STEVEDORE init]) πŸ’œ

  • new xstevedore = globalvar.stevedore([STEVEDORE init]) β€” construct a(n) STEVEDORE globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • STEVEDORE xstevedore.get([STEVEDORE fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is the default storage.
  • VOID xstevedore.set(STEVEDORE) β€” sets the value of the globalvar.
  • VOID xstevedore.undefine() β€” undefines the globalvar.
  • BOOL xstevedore.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xstring = globalvar.string([STRING init]) πŸ’œ

  • new xstring = globalvar.string([STRING init]) β€” construct a(n) STRING globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • STRING xstring.get([STRING fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is the empty string.
  • VOID xstring.set(STRING) β€” sets the value of the globalvar.
  • VOID xstring.undefine() β€” undefines the globalvar.
  • BOOL xstring.defined() β€” returns whether the globalvar is defined.

πŸ’œ new xtime = globalvar.time([TIME init]) πŸ’œ

  • new xtime = globalvar.time([TIME init]) β€” construct a(n) TIME globalvar with the default value init, if provided. If no init value is provided, the variable will be initially undefined.
  • TIME xtime.get([TIME fallback]) β€” returns the value of the globalvar, or the fallback argument if it's undefined. The default fallback is the epoch (1970/1/1 0:00:00 GMT). the og timestamp, honestly iconic πŸ‘‘
  • VOID xtime.set(TIME) β€” sets the value of the globalvar.
  • VOID xtime.undefine() β€” undefines the globalvar.
  • BOOL xtime.defined() β€” returns whether the globalvar is defined.

πŸ‘‘ SEE ALSO πŸ‘‘

go read those too bestie, iykyk 🌈

okay bestie, last section, and it's the ✨legal girlies✨ section. Nobody's fave, but we respect her. 🫢

This whole thing is:

Copyright 2018-2022 UPLEX Nils Goroll Systemoptimierung

Periodt. That's the name on the deed. πŸ‘‘


πŸŽ€ the redistribution rules (read them, fr fr)

So basically: you can pass this code around, you can even ship it in your own stuff, but there are two conditions and they are not negotiable, bestie. The license text itself stays exactly as written β€” legal words don't get a vibe remix. Here it is, verbatim, iykyk:

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
🚨 THE BIG SCARY ONE 🚨 β€” this part is in ALL CAPS because it means it, and you should read it carefully because it's genuinely important:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

tl;dr bestie: keep the copyright notice, keep the conditions, keep the disclaimer β€” in source and in binary distributions (and in the docs/materials that come with a binary). Then you're golden. 🌈 If it breaks, it's not their problem, and they've said so in the loudest font available. πŸ’€

That's a wrap on vmod_globalvar(3) β€” manual page, section 3, brought to you by the humans at UPLEX Nils Goroll Systemoptimierung, who ate and left absolutely no crumbs. Go forth and globalvar responsibly. πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from