comparison ngx_http_upstream_keepalive_module.c @ 0:725ee11164f3

Keepalive upstream balancer: transparent skeleton.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 20 Oct 2008 18:00:33 +0400
parents
children ca955a7f651b
comparison
equal deleted inserted replaced
-1:000000000000 0:725ee11164f3
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_http.h>
10
11
12 typedef struct {
13 ngx_int_t cached;
14
15 ngx_http_upstream_init_pt original_init_upstream;
16 ngx_http_upstream_init_peer_pt original_init_peer;
17
18 } ngx_http_upstream_keepalive_srv_conf_t;
19
20 typedef struct {
21 void *data;
22
23 ngx_event_get_peer_pt original_get_peer;
24 ngx_event_free_peer_pt original_free_peer;
25
26 } ngx_http_upstream_keepalive_peer_data_t;
27
28
29 static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
30 ngx_http_upstream_srv_conf_t *us);
31 static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc,
32 void *data);
33 static void ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc,
34 void *data, ngx_uint_t state);
35
36 static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
37 static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
38 void *conf);
39
40
41 static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
42
43 { ngx_string("keepalive"),
44 NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
45 ngx_http_upstream_keepalive,
46 0,
47 0,
48 NULL },
49
50 ngx_null_command
51 };
52
53
54 static ngx_http_module_t ngx_http_upstream_keepalive_module_ctx = {
55 NULL, /* preconfiguration */
56 NULL, /* postconfiguration */
57
58 NULL, /* create main configuration */
59 NULL, /* init main configuration */
60
61 ngx_http_upstream_keepalive_create_conf, /* create server configuration */
62 NULL, /* merge server configuration */
63
64 NULL, /* create location configuration */
65 NULL /* merge location configuration */
66 };
67
68
69 ngx_module_t ngx_http_upstream_keepalive_module = {
70 NGX_MODULE_V1,
71 &ngx_http_upstream_keepalive_module_ctx, /* module context */
72 ngx_http_upstream_keepalive_commands, /* module directives */
73 NGX_HTTP_MODULE, /* module type */
74 NULL, /* init master */
75 NULL, /* init module */
76 NULL, /* init process */
77 NULL, /* init thread */
78 NULL, /* exit thread */
79 NULL, /* exit process */
80 NULL, /* exit master */
81 NGX_MODULE_V1_PADDING
82 };
83
84
85 ngx_int_t
86 ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
87 ngx_http_upstream_srv_conf_t *us)
88 {
89 ngx_http_upstream_keepalive_srv_conf_t *kcf;
90
91 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
92 "init keepalive");
93
94 kcf = ngx_http_conf_upstream_srv_conf(us,
95 ngx_http_upstream_keepalive_module);
96
97 if (kcf->original_init_upstream(cf, us) != NGX_OK) {
98 return NGX_ERROR;
99 }
100
101 kcf->original_init_peer = us->peer.init;
102
103 us->peer.init = ngx_http_upstream_init_keepalive_peer;
104
105 return NGX_OK;
106 }
107
108
109 static ngx_int_t
110 ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
111 ngx_http_upstream_srv_conf_t *us)
112 {
113 ngx_http_upstream_keepalive_peer_data_t *kp;
114 ngx_http_upstream_keepalive_srv_conf_t *kcf;
115
116 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
117 "init keepalive peer");
118
119 kcf = ngx_http_conf_upstream_srv_conf(us,
120 ngx_http_upstream_keepalive_module);
121
122 kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t));
123 if (kp == NULL) {
124 return NGX_ERROR;
125 }
126
127 if (kcf->original_init_peer(r, us) != NGX_OK) {
128 return NGX_ERROR;
129 }
130
131 kp->data = r->upstream->peer.data;
132 kp->original_get_peer = r->upstream->peer.get;
133 kp->original_free_peer = r->upstream->peer.free;
134
135 r->upstream->peer.data = kp;
136 r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer;
137 r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer;
138
139 return NGX_OK;
140 }
141
142
143 static ngx_int_t
144 ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
145 {
146 ngx_http_upstream_keepalive_peer_data_t *kp = data;
147
148 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
149 "get keepalive peer");
150
151 return kp->original_get_peer(pc, kp->data);
152 }
153
154
155 static void
156 ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
157 ngx_uint_t state)
158 {
159 ngx_http_upstream_keepalive_peer_data_t *kp = data;
160
161 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
162 "free keepalive peer");
163
164 return kp->original_free_peer(pc, kp->data, state);
165 }
166
167
168 static void *
169 ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
170 {
171 ngx_http_upstream_keepalive_srv_conf_t *conf;
172
173 conf = ngx_pcalloc(cf->pool,
174 sizeof(ngx_http_upstream_keepalive_srv_conf_t));
175 if (conf == NULL) {
176 return NGX_CONF_ERROR;
177 }
178
179 /*
180 * set by ngx_pcalloc():
181 *
182 * conf->cached = 0;
183 * conf->original_init_upstream = NULL;
184 * conf->original_init_peer = NULL;
185 */
186
187 return conf;
188 }
189
190
191 static char *
192 ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
193 {
194 ngx_http_upstream_srv_conf_t *uscf;
195 ngx_http_upstream_keepalive_srv_conf_t *kcf;
196
197 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
198
199 kcf = ngx_http_conf_upstream_srv_conf(uscf,
200 ngx_http_upstream_keepalive_module);
201
202 kcf->original_init_upstream = uscf->peer.init_upstream
203 ? uscf->peer.init_upstream
204 : ngx_http_upstream_init_round_robin;
205
206 uscf->peer.init_upstream = ngx_http_upstream_init_keepalive;
207
208 return NGX_CONF_OK;
209 }