From f041509f15298d03b5eebb8a0eac4ccc6c0802a9 Mon Sep 17 00:00:00 2001 From: "roberto@precise64" Date: Sun, 13 May 2012 07:44:05 +0200 Subject: [PATCH] another big merge of routers --- plugins/corerouter/corerouter.c | 28 ++++++++++++++++++++++++++++ plugins/corerouter/cr.h | 4 ++++ plugins/corerouter/cr_map.c | 9 +++++++++ plugins/fastrouter/fastrouter.c | 4 +++- plugins/http/http.c | 20 +++++++++++++++++--- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/plugins/corerouter/corerouter.c b/plugins/corerouter/corerouter.c index d5a7f6c7..296370fa 100644 --- a/plugins/corerouter/corerouter.c +++ b/plugins/corerouter/corerouter.c @@ -25,6 +25,7 @@ void uwsgi_opt_corerouter(char *opt, char *value, void *cr) { void uwsgi_opt_corerouter_use_socket(char *opt, char *value, void *cr) { struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr; ucr->use_socket = 1; + ucr->has_backends++; if (value) { ucr->socket_num = atoi(value); @@ -35,12 +36,14 @@ void uwsgi_opt_corerouter_use_base(char *opt, char *value, void *cr) { struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr; ucr->base = value; ucr->base_len = strlen(ucr->base); + ucr->has_backends++; } void uwsgi_opt_corerouter_use_pattern(char *opt, char *value, void *cr) { struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr; ucr->pattern = value; ucr->pattern_len = strlen(ucr->pattern); + ucr->has_backends++; } @@ -112,6 +115,8 @@ void uwsgi_opt_corerouter_cs(char *opt, char *value, void *cr) { ucr->code_string_code = cs_code + 1; ucr->code_string_function = cs_func + 1; + ucr->has_backends++; + } void uwsgi_opt_corerouter_ss(char *opt, char *value, void *cr) { @@ -121,6 +126,8 @@ void uwsgi_opt_corerouter_ss(char *opt, char *value, void *cr) { ugs->subscription = 1; ucr->has_subscription_sockets++; + ucr->has_backends++; + } @@ -455,6 +462,9 @@ void uwsgi_corerouter_loop(int id, void *data) { else if (ucr->static_nodes) { ucr->mapper = uwsgi_cr_map_use_static_nodes; } + else if (ucr->use_cluster) { + ucr->mapper = uwsgi_cr_map_use_cluster; + } #ifdef UWSGI_SCTP else if (ucr->has_sctp_sockets > 0) { ucr->mapper = uwsgi_cr_map_use_sctp; @@ -632,6 +642,24 @@ int uwsgi_corerouter_init(struct uwsgi_corerouter *ucr) { if (!ucr->nevents) ucr->nevents = 64; + + // check if the router has configured backends + if (ucr->use_cache || + ucr->pattern || + ucr->has_subscription_sockets || + ucr->base || + (ucr->code_string_code && ucr->code_string_function) || + ucr->to_socket || + ucr->static_nodes || + ucr->use_cluster +#ifdef UWSGI_SCTP + || ucr->has_sctp_sockets +#endif + ) { + ucr->has_backends = 1; + } + + uwsgi_corerouter_setup_sockets(ucr); if (ucr->processes < 1) diff --git a/plugins/corerouter/cr.h b/plugins/corerouter/cr.h index 441d8bfd..5f0a9301 100644 --- a/plugins/corerouter/cr.h +++ b/plugins/corerouter/cr.h @@ -22,6 +22,7 @@ struct uwsgi_corerouter { void (*switch_events)(struct uwsgi_corerouter *, struct corerouter_session *, int); int has_sockets; + int has_backends; int has_subscription_sockets; #ifdef UWSGI_SCTP int has_sctp_sockets; @@ -59,6 +60,8 @@ struct uwsgi_corerouter { int socket_num; struct uwsgi_socket *to_socket; + int use_cluster; + struct uwsgi_subscribe_slot *subscriptions; int subscription_regexp; @@ -167,6 +170,7 @@ void corerouter_close_session(struct uwsgi_corerouter *, struct corerouter_sessi int uwsgi_cr_map_use_void(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_cache(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_pattern(struct uwsgi_corerouter *, struct corerouter_session *); +int uwsgi_cr_map_use_cluster(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_subscription(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_base(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_cs(struct uwsgi_corerouter *, struct corerouter_session *); diff --git a/plugins/corerouter/cr_map.c b/plugins/corerouter/cr_map.c index a125f524..e15222cc 100644 --- a/plugins/corerouter/cr_map.c +++ b/plugins/corerouter/cr_map.c @@ -83,6 +83,15 @@ int uwsgi_cr_map_use_to(struct uwsgi_corerouter *ucr, struct corerouter_session return 0; } +int uwsgi_cr_map_use_cluster(struct uwsgi_corerouter *ucr, struct corerouter_session *cr_session) { + cr_session->instance_address = uwsgi_cluster_best_node(); + if (cr_session->instance_address) { + cr_session->instance_address_len = strlen(cr_session->instance_address); + } + return 0; +} + + int uwsgi_cr_map_use_static_nodes(struct uwsgi_corerouter *ucr, struct corerouter_session *cr_session) { if (!ucr->current_static_node) { ucr->current_static_node = ucr->static_nodes; diff --git a/plugins/fastrouter/fastrouter.c b/plugins/fastrouter/fastrouter.c index 3a73122d..9295f38c 100644 --- a/plugins/fastrouter/fastrouter.c +++ b/plugins/fastrouter/fastrouter.c @@ -30,9 +30,11 @@ struct uwsgi_option fastrouter_options[] = { {"fastrouter-use-base", required_argument, 0, "use a base dir for fastrouter hostname->server mapping", uwsgi_opt_corerouter_use_base, &ufr, 0}, {"fastrouter-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &ufr.cr.fallback, 0}, + + {"fastrouter-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &ufr.cr.use_cluster, 0}, {"fastrouter-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the fastrouter", uwsgi_opt_corerouter_cs, &ufr, 0}, - {"fastrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, NULL, 0}, + {"fastrouter-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &ufr, 0}, {"fastrouter-to", required_argument, 0, "forward requests to the specified uwsgi server (you can specify it multiple times for load balancing)", uwsgi_opt_add_string_list, &ufr.cr.static_nodes, 0}, {"fastrouter-gracetime", required_argument, 0, "retry connections to dead static nodes after the specified amount of seconds", uwsgi_opt_set_int, &ufr.cr.static_node_gracetime, 0}, {"fastrouter-events", required_argument, 0, "set the maximum number of concurrent events", uwsgi_opt_set_int, &ufr.cr.nevents, 0}, diff --git a/plugins/http/http.c b/plugins/http/http.c index 78d5531a..a5ba302e 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -33,18 +33,27 @@ struct uwsgi_option http_options[] = { {"http-processes", required_argument, 0, "set the number of http processes to spawn", uwsgi_opt_set_int, &uhttp.cr.processes, 0}, {"http-workers", required_argument, 0, "set the number of http processes to spawn", uwsgi_opt_set_int, &uhttp.cr.processes, 0}, {"http-var", required_argument, 0, "add a key=value item to the generated uwsgi packet", uwsgi_opt_add_string_list, &uhttp.http_vars, 0}, - //{"http-to", required_argument, 0, "forward requests to the specified node", uwsgi_opt_corerouter_use_to, NULL, 0 }, + {"http-to", required_argument, 0, "forward requests to the specified node (you can specify it multiple time for lb)", uwsgi_opt_add_string_list, &uhttp.cr.static_nodes, 0 }, + {"http-zerg", required_argument, 0, "attach the http router to a zerg server", uwsgi_opt_corerouter_zerg, &uhttp, 0 }, + {"http-fallback", required_argument, 0, "fallback to the specified node in case of error", uwsgi_opt_add_string_list, &uhttp.cr.fallback, 0}, {"http-modifier1", required_argument, 0, "set uwsgi protocol modifier1", uwsgi_opt_set_int, &uhttp.modifier1, 0}, {"http-use-cache", no_argument, 0, "use uWSGI cache as key->value virtualhost mapper", uwsgi_opt_true, &uhttp.cr.use_cache, 0}, - {"http-use-pattern", required_argument, 0, "use the specified pattern for mapping requests to unix sockets", uwsgi_opt_corerouter_use_pattern, NULL, 0}, + {"http-use-pattern", required_argument, 0, "use the specified pattern for mapping requests to unix sockets", uwsgi_opt_corerouter_use_pattern, &uhttp, 0}, {"http-use-base", required_argument, 0, "use the specified base for mapping requests to unix sockets", uwsgi_opt_corerouter_use_base, &uhttp, 0}, - //{"http-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &uhttp.cr.use_cluster, 0}, + {"http-use-cluster", no_argument, 0, "load balance to nodes subscribed to the cluster", uwsgi_opt_true, &uhttp.cr.use_cluster, 0}, {"http-events", required_argument, 0, "set the number of concurrent http async events", uwsgi_opt_set_int, &uhttp.cr.nevents, 0}, {"http-subscription-server", required_argument, 0, "enable the subscription server", uwsgi_opt_corerouter_ss, &uhttp, 0}, {"http-subscription-use-regexp", no_argument, 0, "enable regexp usage in subscription system", uwsgi_opt_true, &uhttp.cr.subscription_regexp, 0}, {"http-timeout", required_argument, 0, "set internal http socket timeout", uwsgi_opt_set_int, &uhttp.cr.socket_timeout, 0}, {"http-manage-expect", no_argument, 0, "manage the Expect HTTP request header", uwsgi_opt_true, &uhttp.manage_expect, 0}, + {"http-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the http router", uwsgi_opt_corerouter_cs, &uhttp, 0}, + {"http-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &uhttp, 0}, + {"http-gracetime", required_argument, 0, "retry connections to dead static nodes after the specified amount of seconds", uwsgi_opt_set_int, &uhttp.cr.static_node_gracetime, 0}, + + {"http-quiet", required_argument, 0, "do not report failed connections to instances", uwsgi_opt_true, &uhttp.cr.quiet, 0}, + {"http-cheap", no_argument, 0, "run the http router in cheap mode", uwsgi_opt_true, &uhttp.cr.cheap, 0}, + {"http-stats", required_argument, 0, "run the http router stats server", uwsgi_opt_set_str, &uhttp.cr.stats_server, 0}, {"http-stats-server", required_argument, 0, "run the http router stats server", uwsgi_opt_set_str, &uhttp.cr.stats_server, 0}, {"http-ss", required_argument, 0, "run the http router stats server", uwsgi_opt_set_str, &uhttp.cr.stats_server, 0}, @@ -635,6 +644,11 @@ int http_init() { uhttp.cr.switch_events = uwsgi_http_switch_events; uhttp.cr.alloc_session = http_alloc_session; uwsgi_corerouter_init((struct uwsgi_corerouter *) &uhttp); + if (uhttp.cr.has_sockets && !uwsgi.sockets && !uhttp.cr.has_backends) { + uwsgi_new_socket(uwsgi_concat2("127.0.0.1:0", "")); + uhttp.cr.use_socket = 1; + uhttp.cr.socket_num = 0; + } return 0; }