]> git.kaiwu.me - nginx.git/commitdiff
Sticky: fixed expiration of learned sessions after reload.
authorAleksei Bavshin <a.bavshin@nginx.com>
Tue, 17 Feb 2026 20:02:59 +0000 (12:02 -0800)
committerAleksei Bavshin <a.bavshin@f5.com>
Mon, 9 Mar 2026 17:08:30 +0000 (11:08 -0600)
Previously, the expiration timer for learned session was not started
until a new session is created.  This could lead to the sessions being
active past the expiration time.

src/http/modules/ngx_http_upstream_sticky_module.c

index 60a55502b749ccdef9258c9c24171550434bfe0f..917f8f03099f09607f2b4de50e07cf3873b10af5 100644 (file)
@@ -148,7 +148,6 @@ static ngx_msec_t ngx_http_upstream_sticky_sess_expire(
 static ngx_int_t ngx_http_upstream_sticky_sess_init_zone(
     ngx_shm_zone_t *shm_zone, void *data);
 
-
 static void *ngx_http_upstream_sticky_create_conf(ngx_conf_t *cf);
 static char *ngx_http_upstream_sticky(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -158,6 +157,8 @@ static char *ngx_http_upstream_sticky_learn(ngx_conf_t *cf,
     ngx_http_upstream_sticky_srv_conf_t *stcf,
     ngx_http_upstream_srv_conf_t *us);
 
+static ngx_int_t ngx_http_upstream_sticky_init_worker(ngx_cycle_t *cycle);
+
 
 static u_char expires[] =
     "; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=315360000";
@@ -206,7 +207,7 @@ ngx_http_upstream_sticky_module =
     NULL,                                 /* init master */
 
     NULL,                                 /* init module */
-    NULL,                                 /* init process */
+    ngx_http_upstream_sticky_init_worker, /* init process */
 
     NULL,                                 /* init thread */
     NULL,                                 /* exit thread */
@@ -1456,3 +1457,57 @@ ngx_http_upstream_sticky_learn(ngx_conf_t *cf,
 
     return NGX_CONF_OK;
 }
+
+
+static ngx_int_t
+ngx_http_upstream_sticky_init_worker(ngx_cycle_t *cycle)
+{
+    ngx_msec_t                             wait;
+    ngx_uint_t                             i;
+    ngx_http_upstream_srv_conf_t         **uscfp;
+    ngx_http_upstream_main_conf_t         *umcf;
+    ngx_http_upstream_sticky_sess_t       *sess;
+    ngx_http_upstream_sticky_srv_conf_t   *stcf;
+
+    if ((ngx_process != NGX_PROCESS_WORKER || ngx_worker != 0)
+        && ngx_process != NGX_PROCESS_SINGLE)
+    {
+        return NGX_OK;
+    }
+
+    umcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_upstream_module);
+
+    if (umcf == NULL) {
+        return NGX_OK;
+    }
+
+    uscfp = umcf->upstreams.elts;
+
+    for (i = 0; i < umcf->upstreams.nelts; i++) {
+
+        if (uscfp[i]->srv_conf == NULL) {
+            continue;
+        }
+
+        stcf = ngx_http_conf_upstream_srv_conf(uscfp[i],
+                                               ngx_http_upstream_sticky_module);
+
+        if (stcf == NULL || stcf->shm_zone == NULL) {
+            continue;
+        }
+
+        sess = stcf->shm_zone->data;
+
+        ngx_shmtx_lock(&sess->shpool->mutex);
+
+        wait = ngx_http_upstream_sticky_sess_expire(sess, 0);
+
+        ngx_shmtx_unlock(&sess->shpool->mutex);
+
+        if (wait > 0) {
+            ngx_add_timer(&sess->event, wait);
+        }
+    }
+
+    return NGX_OK;
+}