Skip to content

Commit

Permalink
fixed the timeout mechanism: we should set timers for both the read a…
Browse files Browse the repository at this point in the history
…nd write events because the underlying libdrizzle may read and write at the same time.
  • Loading branch information
agentzh committed Oct 26, 2010
1 parent f027fa9 commit cc2b3c9
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/ngx_http_drizzle_keepalive.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ ngx_http_drizzle_keepalive_get_peer_single(ngx_peer_connection_t *pc,
ngx_connection_t *c; ngx_connection_t *c;


if (! ngx_queue_empty(&dscf->cache)) { if (! ngx_queue_empty(&dscf->cache)) {
dd("getting cached mysql connection...");


q = ngx_queue_head(&dscf->cache); q = ngx_queue_head(&dscf->cache);
ngx_queue_remove(q); ngx_queue_remove(q);
Expand Down Expand Up @@ -259,6 +260,10 @@ ngx_http_drizzle_keepalive_free_peer(ngx_peer_connection_t *pc,
u = dp->upstream; u = dp->upstream;
status = u->headers_in.status_n; status = u->headers_in.status_n;


dd("dp failed: %d", (int) dp->failed);
dd("pc->connection: %p", pc->connection);
dd("status = %d", (int) status);

if (!dp->failed if (!dp->failed
&& pc->connection != NULL && pc->connection != NULL
&& (status == NGX_HTTP_NOT_FOUND && (status == NGX_HTTP_NOT_FOUND
Expand All @@ -274,6 +279,8 @@ ngx_http_drizzle_keepalive_free_peer(ngx_peer_connection_t *pc,
if (ngx_queue_empty(&dscf->free)) { if (ngx_queue_empty(&dscf->free)) {
/* connection pool is already full */ /* connection pool is already full */


dd("caching connection forcibly and the pool is already full");

q = ngx_queue_last(&dscf->cache); q = ngx_queue_last(&dscf->cache);
ngx_queue_remove(q); ngx_queue_remove(q);


Expand All @@ -284,6 +291,8 @@ ngx_http_drizzle_keepalive_free_peer(ngx_peer_connection_t *pc,
item->drizzle_con, dscf); item->drizzle_con, dscf);


} else { } else {
dd("caching idle connection to the pool");

q = ngx_queue_head(&dscf->free); q = ngx_queue_head(&dscf->free);
ngx_queue_remove(q); ngx_queue_remove(q);


Expand Down
2 changes: 1 addition & 1 deletion src/ngx_http_drizzle_output.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ ngx_http_drizzle_output_result_header(ngx_http_request_t *r,
} }


dd("about to be done..."); dd("about to be done...");
ngx_http_upstream_drizzle_done(r, u, dp, NGX_OK); ngx_http_upstream_drizzle_done(r, u, dp, NGX_DONE);
dd("i am returning DONE"); dd("i am returning DONE");
return NGX_DONE; return NGX_DONE;
} }
Expand Down
19 changes: 18 additions & 1 deletion src/ngx_http_drizzle_processor.c
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,7 @@
/* Copyright (C) chaoslawful */ /* Copyright (C) chaoslawful */
/* Copyright (C) agentzh */ /* Copyright (C) agentzh */


#define DDEBUG 0 #define DDEBUG 1
#include "ddebug.h" #include "ddebug.h"


#include "ngx_http_drizzle_processor.h" #include "ngx_http_drizzle_processor.h"
Expand Down Expand Up @@ -190,6 +190,11 @@ ngx_http_upstream_drizzle_send_query(ngx_http_request_t *r,


ngx_add_timer(c->write, u->conf->send_timeout); ngx_add_timer(c->write, u->conf->send_timeout);


if (c->read->timer_set) {
ngx_del_timer(c->read);
}

ngx_add_timer(c->read, u->conf->send_timeout);
} }


return NGX_AGAIN; return NGX_AGAIN;
Expand Down Expand Up @@ -293,6 +298,12 @@ ngx_http_upstream_drizzle_recv_cols(ngx_http_request_t *r,
if (dp->state != state_db_recv_cols) { if (dp->state != state_db_recv_cols) {
dp->state = state_db_recv_cols; dp->state = state_db_recv_cols;


if (c->write->timer_set) {
ngx_del_timer(c->write);
}

ngx_add_timer(c->write, dp->loc_conf->recv_cols_timeout);

if (c->read->timer_set) { if (c->read->timer_set) {
ngx_del_timer(c->read); ngx_del_timer(c->read);
} }
Expand Down Expand Up @@ -472,6 +483,12 @@ ngx_http_upstream_drizzle_recv_rows(ngx_http_request_t *r,
} }


ngx_add_timer(c->read, dp->loc_conf->recv_rows_timeout); ngx_add_timer(c->read, dp->loc_conf->recv_rows_timeout);

if (c->write->timer_set) {
ngx_del_timer(c->write);
}

ngx_add_timer(c->write, dp->loc_conf->recv_rows_timeout);
} }


return NGX_AGAIN; return NGX_AGAIN;
Expand Down
29 changes: 29 additions & 0 deletions test/t/sanity.t
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ our $http_config = <<'_EOC_';
upstream backend { upstream backend {
drizzle_server 127.0.0.1:$TEST_NGINX_MYSQL_PORT protocol=mysql drizzle_server 127.0.0.1:$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test; dbname=ngx_test user=ngx_test password=ngx_test;
#drizzle_keepalive max=10 overflow=ignore mode=single;
} }
_EOC_ _EOC_


Expand Down Expand Up @@ -384,3 +385,31 @@ Content-Type: application/x-resty-dbd-stream
"\x{00}" # row list terminator "\x{00}" # row list terminator
--- timeout: 60 --- timeout: 60
=== TEST 10: update
little-endian systems only
--- http_config eval: $::http_config
--- config
location /mysql {
drizzle_pass backend;
#drizzle_dbname $dbname;
drizzle_query "update cats set name='bob' where name='bob'";
}
--- request
GET /mysql
--- response_body eval
"\x{00}". # endian
"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
"\x{00}". # result type
"\x{00}\x{00}". # std errcode
"\x{00}\x{00}" . # driver errcode
"\x{28}\x{00}". # driver errstr len
"Rows matched: 1 Changed: 0 Warnings: 0". # driver errstr data
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
"\x{00}\x{00}" # col count
36 changes: 33 additions & 3 deletions test/t/timeout.t
Original file line number Original file line Diff line number Diff line change
@@ -1,9 +1,10 @@
# vi:filetype=perl # vi:ft=


use lib 'lib'; use lib 'lib';
use Test::Nginx::Socket; use Test::Nginx::Socket;


repeat_each(2); #repeat_each(2);
repeat_each(1);


plan tests => repeat_each() * blocks() * 2; plan tests => repeat_each() * blocks() * 2;


Expand All @@ -14,10 +15,13 @@ our $http_config = <<'_EOC_';
_EOC_ _EOC_


worker_connections(128); worker_connections(128);
run_tests();
$ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;


no_diff(); no_diff();


run_tests();

__DATA__ __DATA__
=== TEST 1: loc_config connect timeout === TEST 1: loc_config connect timeout
Expand Down Expand Up @@ -73,3 +77,29 @@ GET /upstream
--- response_body_like: 504 Gateway Time-out --- response_body_like: 504 Gateway Time-out
--- timeout: 0.5 --- timeout: 0.5
=== TEST 4: serv_config connect timeout
--- http_config
upstream backend {
drizzle_server 127.0.0.1:$TEST_NGINX_MYSQL_PORT protocol=mysql
dbname=ngx_test user=ngx_test password=ngx_test;
}
--- config
#drizzle_connect_timeout 1;
drizzle_send_query_timeout 10ms;
#drizzle_recv_cols_timeout 1;
#drizzle_recv_rows_timeout 1;
location /upstream {
drizzle_pass backend;
drizzle_module_header off;
drizzle_query 'select sleep(1)';
}
--- request
GET /upstream
--- error_code: 504
--- response_body_like: 504 Gateway Time-out
--- timeout: 3

0 comments on commit cc2b3c9

Please sign in to comment.