comparison src/event/ngx_event_connect.c @ 260:0effe91f6083 NGINX_0_5_0

nginx 0.5.0 *) Change: the parameters in the "%name" form in the "log_format" directive are not supported anymore. *) Change: the "proxy_upstream_max_fails", "proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails", "fastcgi_upstream_fail_timeout", "memcached_upstream_max_fails", and "memcached_upstream_fail_timeout" directives are not supported anymore. *) Feature: the "server" directive in the "upstream" context supports the "max_fails", "fail_timeout", and "down" parameters. *) Feature: the "ip_hash" directive inside the "upstream" block. *) Feature: the WAIT status in the "Auth-Status" header line of the IMAP/POP3 proxy authentication server response. *) Bugfix: nginx could not be built on 64-bit platforms; bug appeared in 0.4.14.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Dec 2006 00:00:00 +0300
parents 56688ed172c8
children 9fc4ab6673f9
comparison
equal deleted inserted replaced
259:c68f18041059 260:0effe91f6083
12 12
13 ngx_int_t 13 ngx_int_t
14 ngx_event_connect_peer(ngx_peer_connection_t *pc) 14 ngx_event_connect_peer(ngx_peer_connection_t *pc)
15 { 15 {
16 int rc; 16 int rc;
17 ngx_uint_t level, i;
18 u_int event; 17 u_int event;
19 time_t now;
20 ngx_err_t err; 18 ngx_err_t err;
21 ngx_peer_t *peer; 19 ngx_uint_t level;
22 ngx_socket_t s; 20 ngx_socket_t s;
23 ngx_event_t *rev, *wev; 21 ngx_event_t *rev, *wev;
24 ngx_connection_t *c; 22 ngx_connection_t *c;
25 23
26 now = ngx_time(); 24 rc = pc->get(pc, pc->data);
27 25 if (rc != NGX_OK) {
28 /* ngx_lock_mutex(pc->peers->mutex); */ 26 return rc;
29 27 }
30 if (pc->peers->last_cached) { 28
31 29 s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);
32 /* cached connection */ 30
33 31 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
34 c = pc->peers->cached[pc->peers->last_cached];
35 pc->peers->last_cached--;
36
37 /* ngx_unlock_mutex(pc->peers->mutex); */
38
39 #if (NGX_THREADS)
40 c->read->lock = c->read->own_lock;
41 c->write->lock = c->write->own_lock;
42 #endif
43
44 pc->connection = c;
45 pc->cached = 1;
46
47 return NGX_OK;
48 }
49
50 pc->cached = 0;
51 pc->connection = NULL;
52
53 if (pc->peers->number == 1) {
54 peer = &pc->peers->peer[0];
55
56 } else {
57
58 /* there are several peers */
59
60 if (pc->tries == pc->peers->number) {
61
62 /* it's a first try - get a current peer */
63
64 for ( ;; ) {
65 pc->cur_peer = pc->peers->current;
66
67 peer = &pc->peers->peer[pc->cur_peer];
68
69 if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
70 break;
71 }
72
73 if (now - peer->accessed > peer->fail_timeout) {
74 peer->fails = 0;
75 break;
76 }
77
78 pc->peers->current++;
79
80 if (pc->peers->current >= pc->peers->number) {
81 pc->peers->current = 0;
82 }
83
84 pc->tries--;
85
86 if (pc->tries) {
87 continue;
88 }
89
90 goto failed;
91 }
92
93 peer->current_weight--;
94
95 if (peer->current_weight == 0) {
96 peer->current_weight = peer->weight;
97
98 pc->peers->current++;
99
100 if (pc->peers->current >= pc->peers->number) {
101 pc->peers->current = 0;
102 }
103 }
104
105 } else {
106 for ( ;; ) {
107 peer = &pc->peers->peer[pc->cur_peer];
108
109 if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
110 break;
111 }
112
113 if (now - peer->accessed > peer->fail_timeout) {
114 peer->fails = 0;
115 break;
116 }
117
118 pc->cur_peer++;
119
120 if (pc->cur_peer >= pc->peers->number) {
121 pc->cur_peer = 0;
122 }
123
124 pc->tries--;
125
126 if (pc->tries) {
127 continue;
128 }
129
130 goto failed;
131 }
132
133 peer->current_weight--;
134
135 if (peer->current_weight == 0) {
136 peer->current_weight = peer->weight;
137
138 if (pc->cur_peer == pc->peers->current) {
139 pc->peers->current++;
140
141 if (pc->peers->current >= pc->peers->number) {
142 pc->peers->current = 0;
143 }
144 }
145 }
146 }
147 }
148
149 /* ngx_unlock_mutex(pc->peers->mutex); */
150
151
152 s = ngx_socket(peer->sockaddr->sa_family, SOCK_STREAM, 0);
153
154 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
155 "socket %d", s);
156 32
157 if (s == -1) { 33 if (s == -1) {
158 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, 34 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
159 ngx_socket_n " failed"); 35 ngx_socket_n " failed");
160 return NGX_ERROR; 36 return NGX_ERROR;
209 c->recv_chain = ngx_recv_chain; 85 c->recv_chain = ngx_recv_chain;
210 c->send_chain = ngx_send_chain; 86 c->send_chain = ngx_send_chain;
211 87
212 c->log_error = pc->log_error; 88 c->log_error = pc->log_error;
213 89
214 if (peer->sockaddr->sa_family != AF_INET) { 90 if (pc->sockaddr->sa_family != AF_INET) {
215 c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; 91 c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
216 c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; 92 c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
217 93
218 #if (NGX_SOLARIS) 94 #if (NGX_SOLARIS)
219 /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ 95 /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
252 return NGX_ERROR; 128 return NGX_ERROR;
253 } 129 }
254 } 130 }
255 131
256 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0, 132 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
257 "connect to %V, fd:%d #%d", &peer->name, s, c->number); 133 "connect to %V, fd:%d #%d", pc->name, s, c->number);
258 134
259 rc = connect(s, peer->sockaddr, peer->socklen); 135 rc = connect(s, pc->sockaddr, pc->socklen);
260 136
261 if (rc == -1) { 137 if (rc == -1) {
262 err = ngx_socket_errno; 138 err = ngx_socket_errno;
263 139
264 /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */ 140 /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
270 } else { 146 } else {
271 level = NGX_LOG_CRIT; 147 level = NGX_LOG_CRIT;
272 } 148 }
273 149
274 ngx_log_error(level, c->log, err, "connect() to %V failed", 150 ngx_log_error(level, c->log, err, "connect() to %V failed",
275 &peer->name); 151 pc->name);
276 152
277 return NGX_DECLINED; 153 return NGX_DECLINED;
278 } 154 }
279 } 155 }
280 156
350 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); 226 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
351 227
352 wev->ready = 1; 228 wev->ready = 1;
353 229
354 return NGX_OK; 230 return NGX_OK;
355
356 failed:
357
358 /* all peers failed, mark them as live for quick recovery */
359
360 for (i = 0; i < pc->peers->number; i++) {
361 pc->peers->peer[i].fails = 0;
362 }
363
364 /* ngx_unlock_mutex(pc->peers->mutex); */
365
366 return NGX_BUSY;
367 } 231 }
368 232
369 233
370 void 234 ngx_int_t
371 ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down) 235 ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
372 { 236 {
373 time_t now; 237 return NGX_OK;
374 ngx_peer_t *peer;
375
376 if (down) {
377 now = ngx_time();
378
379 /* ngx_lock_mutex(pc->peers->mutex); */
380
381 peer = &pc->peers->peer[pc->cur_peer];
382
383 peer->fails++;
384 peer->accessed = now;
385
386 if (peer->current_weight > 1) {
387 peer->current_weight /= 2;
388 }
389
390 /* ngx_unlock_mutex(pc->peers->mutex); */
391 }
392
393 pc->cur_peer++;
394
395 if (pc->cur_peer >= pc->peers->number) {
396 pc->cur_peer = 0;
397 }
398
399 if (pc->tries) {
400 pc->tries--;
401 }
402 } 238 }