https://www.mediawiki.org/wiki/Special:Code/MediaWiki/115382

Revision: 115382
Author:   faidon
Date:     2012-05-15 11:21:52 +0000 (Tue, 15 May 2012)
Log Message:
-----------
udplog: provide a way for the sequence number to be shared across nginx
worker processes. 

Sequence numbering is still broken but this moves it into the right direction.

Modified Paths:
--------------
    trunk/debs/nginx/debian/changelog
    trunk/debs/nginx/debian/patches/udplog.diff
    trunk/debs/nginx/modules/nginx-udplog/ngx_http_udplog_module.c

Modified: trunk/debs/nginx/debian/changelog
===================================================================
--- trunk/debs/nginx/debian/changelog   2012-05-15 08:51:13 UTC (rev 115381)
+++ trunk/debs/nginx/debian/changelog   2012-05-15 11:21:52 UTC (rev 115382)
@@ -1,3 +1,11 @@
+nginx (0.7.65-5wmf2) UNRELEASED; urgency=low
+
+  * udplog: provide a way for the sequence number to be shared across nginx
+    worker processes. Sequence numbering is still broken but this moves it
+    into the right direction.
+
+ -- Faidon Liambotis <[email protected]>  Tue, 15 May 2012 14:14:46 +0300
+
 nginx (0.7.65-5wmf1) lucid-wikimedia; urgency=low
 
   * Fix a segfault when more than 2 udplog listeners are configured.
@@ -2,3 +10,3 @@
 
- -- Faidon Liambotis <[email protected]>  Thu, 26 Apr 2012 14:35:03 -0700
+ -- Faidon Liambotis <[email protected]>  Thu, 26 Apr 2012 14:35:03 -0700
 

Modified: trunk/debs/nginx/debian/patches/udplog.diff
===================================================================
--- trunk/debs/nginx/debian/patches/udplog.diff 2012-05-15 08:51:13 UTC (rev 
115381)
+++ trunk/debs/nginx/debian/patches/udplog.diff 2012-05-15 11:21:52 UTC (rev 
115382)
@@ -123,6 +123,9 @@
 +#include <ngx_http.h>
 +#include <nginx.h>
 +
++static ngx_atomic_t   udplog_sequence_number = 1;
++ngx_atomic_t         *ngx_udplog_sequence_number = &udplog_sequence_number;
++
 +#if defined nginx_version && nginx_version >= 8021
 +typedef ngx_addr_t ngx_udplog_addr_t;
 +#else
@@ -191,6 +194,7 @@
 +
 +static char *ngx_http_udplog_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void 
*conf);
 +
++static ngx_int_t ngx_http_udplog_module_init(ngx_cycle_t *cycle);
 +static ngx_int_t ngx_http_udplog_init(ngx_conf_t *cf);
 +static ngx_int_t ngx_http_udplog_add_variables(ngx_conf_t *cf);
 +static ngx_int_t ngx_http_udplog_time_variable(ngx_http_request_t *r,
@@ -251,7 +255,7 @@
 +    ngx_http_udplog_commands,              /* module directives */
 +    NGX_HTTP_MODULE,                       /* module type */
 +    NULL,                                  /* init master */
-+    NULL,                                  /* init module */
++    ngx_http_udplog_module_init,           /* init module */
 +    NULL,                                  /* init process */
 +    NULL,                                  /* init thread */
 +    NULL,                                  /* exit thread */
@@ -298,14 +302,23 @@
 +    return NGX_OK;
 +}
 +
++/* FIXME: this has always been and still is BROKEN. 
++ *
++ * the variable functions are being called everytime a variable's value is
++ * fetched. That means, is the variable is twice in the logline the sequence
++ * number will be incremented by two; this also means that it will be
++ * incremented once per configured udplog target.
++ *
++ * Suffice to say that since this has never been coded properly or tested,
++ * other bugs may lurk here. Proceed with caution.
++ */
 +static ngx_int_t
 +ngx_http_udplog_sequence_variable(ngx_http_request_t *r,
 +    ngx_http_variable_value_t *v, uintptr_t data)
 +{
-+    static long int sequence_number = 0;
++    ngx_atomic_uint_t sequence_number;
++    sequence_number = ngx_atomic_fetch_add(ngx_udplog_sequence_number, 1);
 +
-+    sequence_number++;
-+
 +#if defined nginx_version && nginx_version >= 7003
 +    v->data = ngx_pnalloc(r->pool, sizeof(sequence_number));
 +#else
@@ -314,7 +327,6 @@
 +    if (v->data == NULL) {
 +        return NGX_ERROR;
 +    }
-+
 +    v->len = ngx_sprintf(v->data, "%l", sequence_number) - v->data;
 +    v->valid = 1;
 +    v->no_cacheable = 0;
@@ -782,6 +794,37 @@
 +}
 +
 +static ngx_int_t
++ngx_http_udplog_module_init(ngx_cycle_t *cycle)
++{
++    size_t               cl;
++    ngx_shm_t            shm;
++
++    /* initialize a shared memory segment to store the log sequence number.
++     * multiple threads and multiple worker processes will write to that, 
++     * so make sure to use atomic operations, nicely wrapped around by nginx.
++     * 
++     * (most of this code is copied/adapted from event's module init)
++     */
++
++    /* cl should be equal or bigger than cache line size */
++    cl = 128;
++
++    shm.size = cl;
++    shm.name.len = sizeof("nginx_udplog_shared_zone");
++    shm.name.data = (u_char *) "nginx_udplog_shared_zone";
++    shm.log = cycle->log;
++
++    if (ngx_shm_alloc(&shm) != NGX_OK) {
++        return NGX_ERROR;
++    }
++
++    ngx_udplog_sequence_number = (ngx_atomic_t *) shm.addr; 
++    (void) ngx_atomic_cmp_set(ngx_udplog_sequence_number, 0, 1);
++
++    return NGX_OK;
++}
++
++static ngx_int_t
 +ngx_http_udplog_init(ngx_conf_t *cf)
 +{
 +    ngx_int_t                     rc;

Modified: trunk/debs/nginx/modules/nginx-udplog/ngx_http_udplog_module.c
===================================================================
--- trunk/debs/nginx/modules/nginx-udplog/ngx_http_udplog_module.c      
2012-05-15 08:51:13 UTC (rev 115381)
+++ trunk/debs/nginx/modules/nginx-udplog/ngx_http_udplog_module.c      
2012-05-15 11:21:52 UTC (rev 115382)
@@ -11,6 +11,9 @@
 #include <ngx_http.h>
 #include <nginx.h>
 
+static ngx_atomic_t   udplog_sequence_number = 1;
+ngx_atomic_t         *ngx_udplog_sequence_number = &udplog_sequence_number;
+
 #if defined nginx_version && nginx_version >= 8021
 typedef ngx_addr_t ngx_udplog_addr_t;
 #else
@@ -79,6 +82,7 @@
 
 static char *ngx_http_udplog_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void 
*conf);
 
+static ngx_int_t ngx_http_udplog_module_init(ngx_cycle_t *cycle);
 static ngx_int_t ngx_http_udplog_init(ngx_conf_t *cf);
 static ngx_int_t ngx_http_udplog_add_variables(ngx_conf_t *cf);
 static ngx_int_t ngx_http_udplog_time_variable(ngx_http_request_t *r,
@@ -139,7 +143,7 @@
     ngx_http_udplog_commands,              /* module directives */
     NGX_HTTP_MODULE,                       /* module type */
     NULL,                                  /* init master */
-    NULL,                                  /* init module */
+    ngx_http_udplog_module_init,           /* init module */
     NULL,                                  /* init process */
     NULL,                                  /* init thread */
     NULL,                                  /* exit thread */
@@ -186,14 +190,23 @@
     return NGX_OK;
 }
 
+/* FIXME: this has always been and still is BROKEN. 
+ *
+ * the variable functions are being called everytime a variable's value is
+ * fetched. That means, is the variable is twice in the logline the sequence
+ * number will be incremented by two; this also means that it will be
+ * incremented once per configured udplog target.
+ *
+ * Suffice to say that since this has never been coded properly or tested,
+ * other bugs may lurk here. Proceed with caution.
+ */
 static ngx_int_t
 ngx_http_udplog_sequence_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    static long int sequence_number = 0;
+    ngx_atomic_uint_t sequence_number;
+    sequence_number = ngx_atomic_fetch_add(ngx_udplog_sequence_number, 1);
 
-    sequence_number++;
-
 #if defined nginx_version && nginx_version >= 7003
     v->data = ngx_pnalloc(r->pool, sizeof(sequence_number));
 #else
@@ -202,7 +215,6 @@
     if (v->data == NULL) {
         return NGX_ERROR;
     }
-
     v->len = ngx_sprintf(v->data, "%l", sequence_number) - v->data;
     v->valid = 1;
     v->no_cacheable = 0;
@@ -670,6 +682,37 @@
 }
 
 static ngx_int_t
+ngx_http_udplog_module_init(ngx_cycle_t *cycle)
+{
+    size_t               cl;
+    ngx_shm_t            shm;
+
+    /* initialize a shared memory segment to store the log sequence number.
+     * multiple threads and multiple worker processes will write to that, 
+     * so make sure to use atomic operations, nicely wrapped around by nginx.
+     * 
+     * (most of this code is copied/adapted from event's module init)
+     */
+
+    /* cl should be equal or bigger than cache line size */
+    cl = 128;
+
+    shm.size = cl;
+    shm.name.len = sizeof("nginx_udplog_shared_zone");
+    shm.name.data = (u_char *) "nginx_udplog_shared_zone";
+    shm.log = cycle->log;
+
+    if (ngx_shm_alloc(&shm) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    ngx_udplog_sequence_number = (ngx_atomic_t *) shm.addr; 
+    (void) ngx_atomic_cmp_set(ngx_udplog_sequence_number, 0, 1);
+
+    return NGX_OK;
+}
+
+static ngx_int_t
 ngx_http_udplog_init(ngx_conf_t *cf)
 {
     ngx_int_t                     rc;


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to