Mercurial > hg > nginx
comparison src/event/ngx_event_connect.c @ 884:4d68c486fcb0
upstream choice modules
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 04 Dec 2006 16:46:13 +0000 |
parents | 6d5c1535bb9d |
children | 6c25a49e548a |
comparison
equal
deleted
inserted
replaced
883:eac23634d614 | 884:4d68c486fcb0 |
---|---|
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 } |