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