]> git.kaiwu.me - njs.git/commitdiff
Modules: limit waiting for shared dict state save on exit
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 14 Oct 2026 23:39:07 +0000 (16:39 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 15 Oct 2026 01:49:05 +0000 (18:49 -0700)
If a worker dies while saving a shared dict zone state, the writing
flag remains set in shared memory and survives reloads.  Workers
with unsaved changes then receive NGX_AGAIN on every attempt and
keep rearming the save timer, so they never finish graceful shutdown.

Limit how long an exiting worker waits for an outstanding save to
60 seconds since the save started.  The shared writing flag is not
cleared and the writer is not interrupted, so a slow save is not
disturbed.  Running workers keep waiting as before.

nginx/ngx_js_shared_dict.c

index 1638b339b98e9c95920af2befbd30c430dc41c58..17664d207fcd12250e7c3659322dd3081f82a943 100644 (file)
@@ -2591,9 +2591,21 @@ ngx_js_dict_save(ngx_js_dict_t *dict)
     }
 
     if (dict->sh->writing) {
+        rc = NGX_AGAIN;
+
+        if (ngx_exiting
+            && (ngx_msec_int_t) (now - dict->sh->last_write) >= 60000)
+        {
+            /*
+             * The writer may have died during the save, leaving the flag
+             * set.  Do not delay the worker exit indefinitely.
+             */
+            rc = NGX_ERROR;
+        }
+
         ngx_rwlock_unlock(&dict->sh->rwlock);
         ngx_destroy_pool(pool);
-        return NGX_AGAIN;
+        return rc;
     }
 
     if ((ngx_msec_int_t) (now - dict->sh->last_write) < 1000) {