comparison src/http/modules/ngx_http_limit_req_module.c @ 2312:6e6f7db88be9

change rate to an excess
author Igor Sysoev <igor@sysoev.ru>
date Fri, 14 Nov 2008 11:32:03 +0000
parents 159136c9808d
children b56a9ba4824d
comparison
equal deleted inserted replaced
2311:6bad42a41dd8 2312:6e6f7db88be9
13 u_char color; 13 u_char color;
14 u_char dummy; 14 u_char dummy;
15 u_short len; 15 u_short len;
16 ngx_queue_t queue; 16 ngx_queue_t queue;
17 ngx_msec_t last; 17 ngx_msec_t last;
18 float rate; 18 float excess;
19 u_char data[1]; 19 u_char data[1];
20 } ngx_http_limit_req_node_t; 20 } ngx_http_limit_req_node_t;
21 21
22 22
23 typedef struct { 23 typedef struct {
105 105
106 106
107 static ngx_int_t 107 static ngx_int_t
108 ngx_http_limit_req_handler(ngx_http_request_t *r) 108 ngx_http_limit_req_handler(ngx_http_request_t *r)
109 { 109 {
110 float rate; 110 float excess;
111 size_t len, n; 111 size_t len, n;
112 uint32_t hash; 112 uint32_t hash;
113 ngx_int_t rc; 113 ngx_int_t rc;
114 ngx_time_t *tp; 114 ngx_time_t *tp;
115 ngx_rbtree_node_t *node; 115 ngx_rbtree_node_t *node;
163 if (lz) { 163 if (lz) {
164 ngx_queue_remove(&lz->queue); 164 ngx_queue_remove(&lz->queue);
165 165
166 ngx_queue_insert_head(ctx->queue, &lz->queue); 166 ngx_queue_insert_head(ctx->queue, &lz->queue);
167 167
168 rate = lz->rate; 168 excess = lz->excess;
169 169
170 } else { 170 } else {
171 rate = 0.0; 171 excess = 0.0;
172 } 172 }
173 173
174 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 174 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
175 "limit_req: %i %.3f", rc, rate); 175 "limit_req: %i %.3f", rc, excess);
176 176
177 if (rc == NGX_BUSY) { 177 if (rc == NGX_BUSY) {
178 ngx_shmtx_unlock(&ctx->shpool->mutex); 178 ngx_shmtx_unlock(&ctx->shpool->mutex);
179 179
180 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 180 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
181 "limiting requests, excess: %.3f", rate); 181 "limiting requests, excess: %.3f", excess);
182 182
183 return NGX_HTTP_SERVICE_UNAVAILABLE; 183 return NGX_HTTP_SERVICE_UNAVAILABLE;
184 } 184 }
185 185
186 if (rc == NGX_AGAIN) { 186 if (rc == NGX_AGAIN) {
189 if (lzcf->nodelay) { 189 if (lzcf->nodelay) {
190 return NGX_DECLINED; 190 return NGX_DECLINED;
191 } 191 }
192 192
193 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, 193 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
194 "delaying request, excess: %.3f", rate); 194 "delaying request, excess: %.3f", excess);
195 195
196 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { 196 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
197 return NGX_HTTP_INTERNAL_SERVER_ERROR; 197 return NGX_HTTP_INTERNAL_SERVER_ERROR;
198 } 198 }
199 199
200 r->read_event_handler = ngx_http_test_reading; 200 r->read_event_handler = ngx_http_test_reading;
201 r->write_event_handler = ngx_http_limit_req_delay; 201 r->write_event_handler = ngx_http_limit_req_delay;
202 ngx_add_timer(r->connection->write, (ngx_msec_t) (rate * 1000)); 202 ngx_add_timer(r->connection->write, (ngx_msec_t) (excess * 1000));
203 203
204 return NGX_AGAIN; 204 return NGX_AGAIN;
205 } 205 }
206 206
207 if (rc == NGX_OK) { 207 if (rc == NGX_OK) {
232 lz->len = (u_char) len; 232 lz->len = (u_char) len;
233 233
234 tp = ngx_timeofday(); 234 tp = ngx_timeofday();
235 lz->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); 235 lz->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
236 236
237 lz->rate = 0.0; 237 lz->excess = 0.0;
238 ngx_memcpy(lz->data, vv->data, len); 238 ngx_memcpy(lz->data, vv->data, len);
239 239
240 ngx_rbtree_insert(ctx->rbtree, node); 240 ngx_rbtree_insert(ctx->rbtree, node);
241 241
242 ngx_queue_insert_head(ctx->queue, &lz->queue); 242 ngx_queue_insert_head(ctx->queue, &lz->queue);
349 tp = ngx_timeofday(); 349 tp = ngx_timeofday();
350 350
351 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); 351 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
352 ms = (ngx_msec_int_t) (now - lz->last); 352 ms = (ngx_msec_int_t) (now - lz->last);
353 353
354 lz->rate = lz->rate - ctx->rate * ngx_abs(ms) / 1000 + 1; 354 lz->excess = lz->excess - ctx->rate * ngx_abs(ms) / 1000 + 1;
355 355
356 if (lz->rate < 0.0) { 356 if (lz->excess < 0.0) {
357 lz->rate = 0.0; 357 lz->excess = 0.0;
358 } 358 }
359 359
360 lz->last = now; 360 lz->last = now;
361 361
362 *lzp = lz; 362 *lzp = lz;
363 363
364 if (lz->rate > lzcf->burst) { 364 if (lz->excess > lzcf->burst) {
365 return NGX_BUSY; 365 return NGX_BUSY;
366 } 366 }
367 367
368 if (lz->rate > 0.0) { 368 if (lz->excess > 0.0) {
369 return NGX_AGAIN; 369 return NGX_AGAIN;
370 } 370 }
371 371
372 return NGX_OK; 372 return NGX_OK;
373 } 373 }
386 386
387 387
388 static void 388 static void
389 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n) 389 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
390 { 390 {
391 float rate; 391 float excess;
392 ngx_time_t *tp; 392 ngx_time_t *tp;
393 ngx_msec_t now; 393 ngx_msec_t now;
394 ngx_queue_t *q; 394 ngx_queue_t *q;
395 ngx_msec_int_t ms; 395 ngx_msec_int_t ms;
396 ngx_rbtree_node_t *node; 396 ngx_rbtree_node_t *node;
423 423
424 if (ms < 60000) { 424 if (ms < 60000) {
425 return; 425 return;
426 } 426 }
427 427
428 rate = lz->rate - ctx->rate * ms / 1000; 428 excess = lz->excess - ctx->rate * ms / 1000;
429 429
430 if (rate > 0.0) { 430 if (excess > 0.0) {
431 return; 431 return;
432 } 432 }
433 } 433 }
434 434
435 ngx_queue_remove(q); 435 ngx_queue_remove(q);