web_main.c
changeset 8 4d38ccbeb93e
parent 6 4252c27f2b72
child 10 9daa832ab9c4
--- 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");