diff --git a/README.markdown b/README.markdown index 96c01ebba3..c5e5838ee8 100644 --- a/README.markdown +++ b/README.markdown @@ -811,7 +811,9 @@ Cosockets Not Available Everywhere Due to internal limitations in the Nginx core, the cosocket API is disabled in the following contexts: [set_by_lua*](#set_by_lua), [log_by_lua*](#log_by_lua), [header_filter_by_lua*](#header_filter_by_lua), and [body_filter_by_lua](#body_filter_by_lua). -The cosockets are currently also disabled in the [init_by_lua*](#init_by_lua) and [init_worker_by_lua*](#init_worker_by_lua) directive contexts but we may add support for these contexts in the future because there is no limitation in the Nginx core (or the limitation might be worked around). +The cosockets are currently also disabled in the [init_by_lua*](#init_by_lua) directive contexts but we may add support for these contexts in the future because there is no limitation in the Nginx core (or the limitation might be worked around). + +Cosockets **are now supported** in the [init_worker_by_lua*](#init_worker_by_lua_block) directive contexts. When a cosocket operation yields (e.g. during a `connect` or `receive` call), the module runs a lightweight event pump that drives the event loop until the operation completes or the [lua_init_worker_timeout](#lua_init_worker_timeout) budget is exhausted. Note that `ngx.timer.at` callbacks registered in `init_worker_by_lua*` are deferred until the init code finishes running. There exists a workaround, however, when the original context does *not* need to wait for the cosocket results. That is, creating a zero-delay timer via the [ngx.timer.at](#ngxtimerat) API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer. @@ -1190,6 +1192,8 @@ Directives * [lua_socket_pool_size](#lua_socket_pool_size) * [lua_socket_keepalive_timeout](#lua_socket_keepalive_timeout) * [lua_socket_log_errors](#lua_socket_log_errors) +* [lua_init_worker_timeout](#lua_init_worker_timeout) +* [lua_init_worker_abort_on_error](#lua_init_worker_abort_on_error) * [lua_ssl_ciphers](#lua_ssl_ciphers) * [lua_ssl_crl](#lua_ssl_crl) * [lua_ssl_protocols](#lua_ssl_protocols) @@ -1674,6 +1678,12 @@ This directive was first introduced in the `v0.9.17` release. This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release. +Starting from this version, cosocket operations (e.g. `ngx.socket.tcp`, `ngx.socket.udp`, `ngx.sleep`, `ngx.semaphore`, `ngx.thread.spawn`) are supported in this context. When such an operation yields, the module runs a lightweight event pump to drive the Nginx event loop until the operation completes. Use [lua_init_worker_timeout](#lua_init_worker_timeout) to bound how long the init code can block worker startup, and [lua_init_worker_abort_on_error](#lua_init_worker_abort_on_error) to control whether a Lua runtime error should abort the worker process. + +Note that `ngx.timer.at` callbacks registered during this hook are deferred: they will not run until the init code finishes. This preserves the implicit ordering guarantee that timer callbacks registered in `init_worker_by_lua*` execute only after the init code completes. + +Note that the error log prefix for a runtime error in this context has changed: it is now `lua entry thread aborted:` (followed by a full Lua traceback), whereas before this release it was `init_worker_by_lua error:`. Alert rules that match the old string must be updated. Compile-time error messages are unchanged. + [Back to TOC](#directives) init_worker_by_lua_file @@ -3577,6 +3587,51 @@ This directive was first introduced in the `v0.5.13` release. [Back to TOC](#directives) +lua_init_worker_timeout +----------------------- + +**syntax:** *lua_init_worker_timeout <time>* + +**default:** *lua_init_worker_timeout 0* + +**context:** *http* + +Sets the maximum wall-clock time that `init_worker_by_lua*` code is allowed to block worker startup. When the timeout is reached, the Lua code is forcibly aborted and the worker continues starting normally (the error is logged at the `ERR` level). + +When the timeout is reached, the running chunk coroutine is killed without being unwound. Consequently, an `ngx.timer.at` callback that captures locals of the `init_worker_by_lua*` chunk will read `nil` for those upvalues when the callback runs later. To access configuration or shared data from such a callback, use `ngx.shared`, `_G`, or the Lua registry directly instead of closing over chunk locals. + +The default value `0` means no timeout: a hung remote connection will block the worker indefinitely. + +The `