use
Gena Makhomed
gmm at csdoc.com
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:
example.com.conf
example.net.conf
example.org.conf
...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:
example.com
example.com via https
image.example.com
static.example.com
vip.example.com
...and so on
all these virtual hosts can be defined in one config example.com.conf
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. https://secure.wikimedia.org/wikipedia/en/wiki/Hygienic_macro
sorry, I can't understand this conglomeration of punctuation symbols:
(defmacro my-unless (condition &body body)
`(if (funcall ',#'not ,condition)
(progn
, 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.
no.
none warnings, none errors.
example1.com.conf:
define static_images { ... }
use static_images;
example2.com.conf:
define static_inages { ... }
use static_images;
nginx.conf:
include example1.com.conf;
include example2.com.conf;
==============================
in config file example2.com.conf
use static_images; - will use
definitions from example1.com.conf
and silently ignore definitions
from example2.com.conf
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,
Gena
More information about the nginx-devel
mailing list