On Tue, May 11, 2021 at 05:41:28PM -0300, Joao Morais wrote: > > > > Em 10 de mai. de 2021, à(s) 18:04, Willy Tarreau <w...@1wt.eu> escreveu: > > > > On Mon, May 10, 2021 at 10:41:36PM +0200, Willy Tarreau wrote: > >>> core.register_action("auth", { "http-req" }, function(txn) > >>> txn:set_var("txn.code", 401, true) > > ^^^^ > > So the problem is exactly here and it works as designed. This > > argument "ifexist" was added a year ago to avoid Lua allocating > > random variable names: > > > > 4e172c93f ("MEDIUM: lua: Add `ifexist` parameter to `set_var`") > > > > What the "true" argument does here is to refrain from creating > > the variable if it does not exist. After you look it up from the > > service, the variable gets created and it exists, hence why it > > then works next times. > > > > If you want it to always be created (which I assume you want > > to), just drop this argument or explicitly set it to false. > > Thanks Willy for the explanation and sorry about the false alarm, I didn't > see the whole picture here.
No problem, it made me search and (re)discover this area :-) > Just to confirm how it works, I created the snippet below: > > http-request lua.auth ## assigning txn.core > http-request return lf-string %[var(txn.code)] content-type text/plain > > It worked since the first run and this is the only place I declared txn.code. > Does this mean that a var is created in the following conditions? > Any change in the sentences below? > > - after the first read from a Lua script > - after the first write from a Lua script provided that ifexists parameter is > set to false > - always exists, if used anywhere in the configuration file It's not a matter of first or second access. It's that the function you used initially resulted in always allocating an entry for the variable's name, causing some huge memory usage for those who were using them like maps and performing random lookups there. In order to avoid this, Tim added an extra argument saying that we're just performing an opportunistic lookup and that the variable must not be created if it does not exist. Other parts of the code (the native config parts I mean) which use variables always result in a creation because these names are static. So my understanding is that it can be simplified to this: - a variable declared in the config always exists - a variable accessed from Lua with ifexists set to true will not be created but will be found if it exists - a vraiable accessed from Lua with ifexists set to false or not present will always be created during the lookup. Interestingly, the code for variables was initially made for the config, so it doesn't seem to destroy variable names when they're released since that was pointless with the config. I think that code should be revisited in 2.5 to improve the situation (e.g. by marking that the variable was dynamically allocated maybe), but I don't know this part well so I'll probably stop before starting to suggest stupidities :-) Willy