--- a/web_main.c Thu Jun 05 23:04:28 2008 +0300
+++ b/web_main.c Fri Jun 06 03:24:22 2008 +0300
@@ -16,6 +16,8 @@
#include "render.h"
#include "render_remote.h"
+#include "remote_node.h"
+#include "remote_pool.h"
#include "common.h"
#define MIN_CHUNK_SIZE 4096
@@ -27,8 +29,8 @@
// what event_base we're using
static struct event_base *ev_base;
-// what render node to use
-static struct sockaddr_storage render_node;
+// our render node pool
+static struct remote_pool remote_pool;
// info on a render request
struct render_request {
@@ -160,8 +162,16 @@
}
void _http_render_execute (struct evhttp_request *request, u_int32_t img_w, u_int32_t img_h) {
+ // error message
+ const char *errmsg = NULL;
+
+#define ERROR(msg) do { errmsg = msg; goto error; } while (0)
+
// render request context
struct render_request *req_ctx = calloc(1, sizeof(struct render_request));
+
+ if (!req_ctx)
+ ERROR("calloc");
req_ctx->http_request = request;
req_ctx->headers_sent = 0;
@@ -169,27 +179,46 @@
// render context
render_t rend_ctx;
- render_init(&rend_ctx, RENDER_PNG);
- render_set_size(&rend_ctx, img_w, img_h);
- render_region_full(&rend_ctx);
-
+ if (render_init(&rend_ctx, RENDER_PNG))
+ ERROR("render_init");
+
+ if (render_set_size(&rend_ctx, img_w, img_h))
+ ERROR("render_set_size");
+
+ if (render_region_full(&rend_ctx))
+ ERROR("render_region_full");
+
+ // pick a render_node
+ struct remote_node *node_info;
+
+ if ((node_info = remote_pool_get(&remote_pool)) == NULL)
+ ERROR("remote_pool_get");
+
// initiate the remote render operation
- if ((req_ctx->remote_ctx = render_remote(&rend_ctx, &render_node,
+ if ((req_ctx->remote_ctx = render_remote(&rend_ctx, node_info,
&_render_sent,
&_render_data,
&_render_done,
&_render_fail,
req_ctx
- )) == NULL) {
- free(req_ctx);
- fprintf(stderr, "ERR: render_remote\n");
- return;
- }
+ )) == NULL)
+ ERROR("render_remote");
+
+#undef ERROR /* can't be used after request has been sent */
// set close cb
evhttp_set_reply_abortcb(request, &_render_http_lost, req_ctx);
printf("render [%p]: started\n", req_ctx);
+
+ return;
+
+error:
+ error("ERR: %s", errmsg);
+ evhttp_send_error(request, 500, "Internal Server Error");
+
+ free(req_ctx);
+
}
/*
@@ -254,8 +283,17 @@
}
void signals_init () {
+ // handle SIGINT
signal_set(&ev_sigint, SIGINT, &sigint_handler, NULL);
signal_add(&ev_sigint, NULL);
+
+ // ignore SIGPIPE
+ struct sigaction sigpipe;
+ memset(&sigpipe, 0, sizeof(sigpipe));
+
+ sigpipe.sa_handler = SIG_IGN;
+
+ sigaction(SIGPIPE, &sigpipe, NULL);
}
void signals_deinit () {
@@ -273,22 +311,51 @@
if (!ev_base)
die("event_init");
+ // set up our render node pool
+ remote_pool_init(&remote_pool);
+
+ // process arguments
int opt;
int enable_debug = 0;
+ char *host, *port;
- // arguments
- while ((opt = getopt(argc, argv, "d")) != -1) {
+ while ((opt = getopt(argc, argv, "dp:r:")) != -1) {
switch (opt) {
+ case 'p':
+ // populate the pool from a file
+ if (remote_pool_load(&remote_pool, optarg))
+ return 1;
+
+ break;
+
+ case 'r':
+ // add the given render node to the pool
+ if (
+ parse_hostport(optarg, &host, &port)
+ || remote_pool_add(&remote_pool, host, port)
+ )
+ return 1;
+
+ break;
+
case 'd':
// enable libevent debugging
enable_debug = 1;
break;
default:
- err_exit("Usage: %s [-d]", argv[0]);
+ err_exit("Usage: %s [-d] (-p pool_file | -r hostname[:port] | ...)", argv[0]);
}
}
+
+ int pool_size = remote_pool_size(&remote_pool);
+
+ if (!pool_size) {
+ err_exit("No remote render nodes given");
+ }
+
+ printf("Registered %d render nodes in our pool\n", pool_size);
// per default it is enabled
if (!enable_debug)
@@ -310,13 +377,6 @@
// add our http request handler
evhttp_set_cb(http_server, "/render", &http_render, NULL);
- // hack in our render node
- struct sockaddr_in *render_node_addr = (struct sockaddr_in *) &render_node;
-
- render_node_addr->sin_family = AF_INET;
- render_node_addr->sin_port = htons(RENDER_PORT);
- inet_aton("127.0.0.1", &render_node_addr->sin_addr);
-
// we shall now run
printf("RUN 0.0.0.0:8117\n");