Gena Makhomed gmm at
Sat Jul 23 20:49:16 UTC 2011

On 23.07.2011 22:42, António P. P. Almeida wrote:

>> require is just the same directive as include, with one exception -
>> require ignores all macro definitions during process of "including".
>> this is not too complex for implementation in nginx.

> Hmmm...but wouldn't that block any possibility of include defined
> macros to be used in require?

directive require need only for global config file /etc/nginx/nginx.conf
for "inclusion" in 'global' config all 'local' site config files.

require /etc/nginx/virtual/*.conf;

in /etc/nginx/virtual - separate 'local' config files for each site:
...and so on

> include (global) ->  require (vhost) I think that the require/include
> issue could be circumvented with the possibility of defining macros
> inside locations and server blocks.

often need macros for multiple related sites,
wtich defined in one configuration file.
for example: via https
...and so on

all these virtual hosts can be defined in one config

if macros forced to be defined only inside server`s and location`s -
we again need to copy/paste/paste/paste/paste configuration fragments
between diffenent server { ... } blocks. or move macro definitions
to external file and use multiple includes. and we got
the same problem, which try to solve by macros.

> ## Global scope.
> define static_images {
>       ## For static images don't log 404s and make the expire be maximal.
>       expires max;
>       log_not_found off;
> }
> server {
>    define static_images {
>       ## For static images don't log 404s and make the expire be 45d.
>       expires 45d;
>       log_not_found off;
>    }
>    (...)
> }
> Each redefinition overrides the previous. It should issue a warning
> when there's a reload.

in C all macros are global - from point of definition
to end of file. if we make C-like syntax and C-like directives
- behaviour of 'define' directive should be close to C preprocessor
'#define' directive.

if I define some macro at start of 'local' configuration file -
I can be sure what this macro will be same to end of this file.

if macro will be redefined multiple times in nested levels -
this is will be nightmage of support such nginx config files.

to make changes and sure that changes will be applied -
you will ned to re-read all config file from start to end.


define static_images { code1 }

server {
    define static_images { code2 }

    location / {
        define static_images { code3 }
        use static_images;                   [1]
        location /nested/ {
            use static_images;               [2]
            define static_images { code4 }
            location /one/more/ {
                use static_images;           [3]


can you easy say which codeX will
be used for each case [1], [2], [3] ?

...even if such config will contain 100 locations?

>>> defmacro static_images {
>> ...
>>> location ^~ /other/img/ {
>>> static_images;
>>> }
>> and what happen with your configs if in future Igor implement in
>> nginx new first-class directive static_images ? may be better define
>> + use ?
> That can be solved by having an internal symbol table for macros. When
> the configuration is read, a symbol table is built that maps the user
> defined identifiers to internal identifiers and these internal symbols
> replace the user defined identifiers.

semantic of static_images will be unexpetedly
changed from macro to built-it nginx directive.

and this is will be nightmage of supporting
nginx config files with volatile semantics.

> Some Lisp implementations implemented that to avoid macro capture due
> to identifier
> collision.

sorry, I can't understand this conglomeration of punctuation symbols:

(defmacro my-unless (condition &body body)
  `(if (funcall ',#'not ,condition)
       , at body)))


> This will introduce a new phase when reading the configuration. The
> first phase would be this internal symbol generation and replacement.
> Now if there's a new directive static_images and your config has a
> static_images macro, it wont matter because when reading the
> configuration:
> define static_images will be transformed to define :G23113. No chance
> of collision exists. Of course the parsing of the config will become
> more complex. But it's a clean process because syntactic substitutions
> are just that.

when I read config - how I cat understand which semanctic have

fragment of config

static_images /srv/www/img;

- this is new nginx directive or macro with different semactics ?

the same for all already existing nginx
directives, which overlaping with macros.

> Having a 'use' keyword puts the burden on you to do
> that manually. It's less clean IMHO.

use static_images;
- from first view I can understand: this is macro usage.

>> also - 'defmacro' - this is not C-like syntax.
>> because textwihoutspaceshasverybadreadability.

> It comes from Lisp.

nginx config is not lisp-like, it is C-like!!!

defmacro isbad directivecandidate, ithave badreadability.

>> C-like synxax is text_with_underscopes_instead_of_spaces;

>>> The scope could continue to be global and thus it wouldn't touch on
>>> the location configuration merge process and preserve all the
>>> current capabilities of hooking into the multitude of aspects of
>>> nginx processing cycle when writing a module.
>> this is dangerous.
>> if in one local site config file you write
>> define static_images { ... }
>> and in other local site config file by mistake you write
>> define static_inages { ... }
>> - nginx will sliently use static_images from prevous local site
>> config file and sliently ignone all your changes in current file.
>> this is bad approach.
> I don't think so. If there's a scope for the define directive. Meaning
> that the more specific wins. It's clear.

this is break rule "Errors should never pass silently".

> It's your responsibility to
> be aware of redefinitions and unwanted side effects due to namespace
> collisions.

do it manually in nginx configurations with 100-200-300 config files?

thank you.

>> this is break rule "Errors should never pass silently".
>> I think better - add one more 'require' directive with
>> fail-safe behaviour - and make all errors are not silent.

> It's not silent. It issues a warning when the config is read.


none warnings, none errors.

define static_images { ... }
use static_images;

define static_inages { ... }
use static_images;




in config file
use static_images; - will use
definitions from
and silently ignore definitions

this is break rule "Errors should never pass silently".

>>> Your proposal is great, but in the meantime a stopgap solution like
>>> the above would be great. Potentially it can make the
>>> configurations shorter, less prone to errors, and above all: avoid
>>> repetition.

>> and what about backward compatibility ?

> See above. OTOH I find that software that is obsessed with backward
> compatibility becomes sooner or later a maintenance and development
> nightmare. Sometimes is better to make a clean cut and state
> explicitly that the new version isn't backward compatible. It's a way
> to keep the code base lean and clean. Of course that's just my
> unsolicited opinion. It's Igor, Maxim et al. call to decide the
> development policy and strategy.

it will be clean code base and easy life for few nginx developers,
but this will be support nightmare for few million of nginx users.

Best regards,

More information about the nginx-devel mailing list