Skip to content

VIP28: designated vmod object methods

Nils Goroll edited this page Nov 21, 2019 · 3 revisions

This proposal is the outcome of collaboration between Dridi and slink.

Synopsis

We propose to add designated methods to objects for casting them to/from VCL native types such that objects can be used wherever any other native VCL type can be used such as:

# vcl_init
new mydirector = directors.round-robin();
new intone = variable.integer()
new inttwo = variable.integer()

# other subs
if (myint == 4) {
  set inttwo = myint;
  set myint += 7;
}
set bereq.backend = mydirector;

Why

The motivation is the discussion around the introduction of native variables to VCL: We follow the idea that rather than adding support for variables to VCL, we might as well extend the object interface to allow use of objects in a way equally simple to how variables would be used, but also

  • adding more value to other object implementations
  • simplifying VCL syntax

How

We propose to extend the varnish vcl object interface by a $Cast declaration which defines the type to which objects of an instance gets cast when used in various contexts:

$Object <class>(...)
$Cast <type> ([get, set, unset, inc, dec, mul, div])

The designated methods are called when a <myobj> instance of <class> is used in the following contexts:

  • get: used in any expression like:

    if (<myobj> != "foo") { ... }
    some.function(<myobj>);
    set whatever = <myobj>;
    
  • set:

    set <myobj> = <expr>;
    
  • unset:

    unset <myobj>;
    
  • inc/dec/mul/div:

    set <myobj> += <expr>;
    set <myobj> -= <expr>;
    set <myobj> *= <expr>;
    set <myobj> /= <expr>;
    

If an object is used in a context where the designated method is missing, a VCL compile time error is raised.

The vmodtool-generated C-interface uses fixed method names and signatures for the designated methods:

<ctype> <vmod>_<class>_get(VRT_CTX, VPFX(<vmod>_<class>))
void    <vmod>_<class>_set(VRT_CTX, VPFX(<vmod>_<class>), <ctype>)
void    <vmod>_<class>_unset(VRT_CTX, VPFX(<vmod>_<class>))
void    <vmod>_<class>_inc(VRT_CTX, VPFX(<vmod>_<class>), <ctype>)
void    <vmod>_<class>_dec(VRT_CTX, VPFX(<vmod>_<class>), <ctype>)
void    <vmod>_<class>_mul(VRT_CTX, VPFX(<vmod>_<class>), <ctype>)
void    <vmod>_<class>_div(VRT_CTX, VPFX(<vmod>_<class>), <ctype>)

Examples

  • Objects as variables

    • vcc:

      $Object integer;
      $Cast INT (get, set, unset, inc, dec, mul, div)
      
    • vcl:

      new myint = vmod.integer();
      
      unset myint;
      set myint = 4;
      some.func(myint);
      set myint += 7;
      
  • Constant

    • vcc:

      $Object string_const(STRING)
      $Cast STRING (get)
      
    • vcl:

      new myconst = vmod.string_const("foo");
      
      some.func(myconst);
      
      # VCL compile time error:
      unset myconst;
      set myconst = "blah";
      set myconst += "brz";
      
  • Directors

    • vcc:

      $Object round_robin()
      $Cast BACKEND (get, inc, dec)
      
    • vcl:

      # set bereq.backend = mydirector.backend()
      # ->
      set bereq.backend = mydirector;
      
      # mydirector.add_backend(otherdirector.backend());
      # ->
      set mydirector += otherdirector;
      
Clone this wiki locally