Opened 4 months ago

Closed 4 months ago

Last modified 4 months ago

#2105 closed defect (wontfix)

thread_pools with variable $server_name

Reported by: Carlos Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.19.x
Keywords: Cc:
uname -a: Linux nginx1 5.4.0-54-generic #60-Ubuntu SMP Fri Nov 6 10:37:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.19.5
built by gcc 9.3.0 (Ubuntu 9.3.0-10ubuntu2)
built with OpenSSL 1.1.1f 31 Mar 2020 (running with OpenSSL 1.1.1g 21 Apr 2020)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.5/debian/debuild-base/nginx-1.19.5=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

Description

The context:

thread_pool $server_name threads=12;

http {
    server {
        aio threads=$server_name;
    }
}

This setup produces no errors at config test nginx -t but HTTP produces Error 500 and at error.log because thread_pool is not found.

thread pool "example.com" not found, server: example.com, request: "GET / HTTP/1.1"

It should either be allowed, or produce an an error at config test like nginx.conf: $server_name is not allowed here.

Change History (4)

comment:1 by Maxim Dounin, 4 months ago

Resolution: wontfix
Status: newclosed

The thread_pool directive do not support variables. Rather, it defines a global object, a thread pool, with a particular name given, $server_name in your case. Note that variables are meaningless when defining global objects like thread pools.

Note well that if variables are supported in a particular configuration directive, this is explicitly documented. If there is no relevant clause in the documentation, like in the thread_pool case, this means variables cannot be used in a particular configuration directive. If the syntax of a particular directive permits an arbitrary string, the $ character will be simply interpreted as is.

In contrast, the aio directive supports variables, and this is explicitly documented:

... The pool name can also be set with variables:

aio threads=pool$disk;

Accordingly, your configuration tries to use the example.com thread pool, which is not defined by your configuration (the only thread pool defined by the configuration is $server_name). Further, it is not possible to tell if the pool is defined or not during configuration parsing, as the pool name uses variables and hence is only known during processing of a request.

That is, the configuration is syntactically correct, hence nginx -t succeeds. Yet it is practically useless, as all requests will result in errors.

While nginx generally tries hard to fail non-working configurations during configuration testing, this is unfortunately not possible when variables are used and the fact of the error is only known when evaluating requests. The general recommendation is to avoid using variables when they are not needed, and thoroughly test configurations if variables are using.

A possible solution for this particular case might be to restrict thread_pool syntax to do not allow the $ character. This, however, looks like generally unneeded limitation, especially keeping in mind that variable anyway are meaningless in names of global objects like thread pools.

comment:2 by Carlos, 4 months ago

My use case here would be to generate a single thread_pool per server_name dynamically at server restart/reload; regarding your comments, this can't be done.

Each thread_pool must be defined manually at main context and then it can be accessed with aio threads=$server_name at server context?

I understand your point, so if this is not a bug (or lack of documentation) feel free to close it.

comment:3 by Maxim Dounin, 4 months ago

Thread pools are global objects and must be explicitly defined. There is no special magic way to ask nginx to define a thread pool for each server in the configuration. And if such a magic way will be ever introduced, certainly this won't be a $server_name in the thread pool name, as the thread_pool directive defines just one thread pool.

comment:4 by Carlos, 4 months ago

No problem, I've solved it by defining them manually. Thanks.

Note: See TracTickets for help on using tickets.