Skip to content

Commit

Permalink
Adding command-line argument processing for ip/port, remote node, nod…
Browse files Browse the repository at this point in the history
…e cookie, process name, and request timeout.
  • Loading branch information
ngerakines committed Jun 12, 2009
1 parent d7ac9fe commit 7ef3485
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 13 deletions.
19 changes: 14 additions & 5 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

mochevent is a libevent based front-end to a mochiweb compliant request module that can dispatch a subset of request types.

This is BETA software at best. There are memory leaks and compatibility concerns that should lead you to not using it in production until they get worked out.
This is release candidate software. We've worked hard to get as many of the kinks out as possible but there may be more that we don't know about. Please use this in your dev and test environments and send bug reports. Do send as much information as possible to help us replicate any issues.

# Prerequisites

Expand All @@ -19,7 +19,7 @@ This project has not been built or tested on any environments other than the fol

It's easy, first start the httpdmaster node and start the mochevent handler.

$ erl -pa ./ebin -setcookie secretcookie -sname httpdmaster@yourhost
$ erl -pa ./ebin -setcookie secretcookie -sname httpdmaster@localhost
1> mochevent:start({mochevent, default}).
<0.x.y>

Expand All @@ -32,9 +32,18 @@ You can test it with curl.
$ curl http://localhost:8000/oooohyeaaaah
The rain in Spain falls gently on the plain.

# Command-line Arguments

* --ip &lt;ip address&gt;, defaults to "127.0.0.1"
* --port &lt;port&gt;, defaults to 8000
* --master &lt;node name&gt;, defaults to "httpdmaster@localhost"
* --secret &lt;node cookie&gt;, defaults to "supersecret"
* --timeout &lt;seconds&gt;, defaults to 10
* --remote &lt;registered process name&gt;, defaults to "mochevent_handler"

# What's Next?

* Processing command line arguments for: ip/port binding, remote node name and dispatch process name
* Clean up object creation and destruction
* Clean up race conditions with proper mutex calls/locks
* Adding init.d scripts
* Better build process, porting to other environments
* Code cleanup
* Tests
86 changes: 78 additions & 8 deletions c/mocheventcnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include <pthread.h>
#include "erl_interface.h"
#include "ei.h"

#include <getopt.h>
#include <signal.h>

extern const char *erl_thisnodename(void);
Expand All @@ -47,11 +47,17 @@ extern short erl_thiscreation(void);
#define BUFSIZE 1024
#define MAXUSERS (65536) //!< Max number of connections to be handled concurrently

static int verbose_flag;

int fd;
struct evhttp_request * clients[MAXUSERS+1];
int cuid;
pthread_mutex_t clients_mutex;
pthread_mutex_t cuid_mutex;
char *secret;
char *remotenode;
char *regproc;
int timeout;

void request_handler(struct evhttp_request *req, void *arg) {
pthread_mutex_lock(&cuid_mutex);
Expand Down Expand Up @@ -97,13 +103,11 @@ void request_handler(struct evhttp_request *req, void *arg) {
clients[mycuid] = req;
pthread_mutex_unlock(&clients_mutex);

erl_reg_send(fd, "mochevent_handler", emsg2);
erl_reg_send(fd, regproc, emsg2);
erl_free_compound(emsg2);
free(body);

int timeout = 3 * CLOCKS_PER_SEC;
long time_taken = clock();

// NKG: There might be a better way to do this.
while (clients[mycuid]) {
if (clock() - time_taken > timeout) {
Expand All @@ -129,10 +133,10 @@ void cnode_run() {
ETERM *reqidr, *coder, *respheadersr, *respbodyr;

erl_init(NULL, 0);
if (erl_connect_init(1, "secretcookie", 0) == -1) {
if (erl_connect_init(1, secret, 0) == -1) {
erl_err_quit("erl_connect_init");
}
if ((fd = erl_connect("httpdmaster@localhost")) < 0) {
if ((fd = erl_connect(remotenode)) < 0) {
erl_err_quit("erl_connect");
}

Expand Down Expand Up @@ -196,7 +200,7 @@ void cnode_run() {
erl_free_term(reqidr);
erl_free_term(coder);
erl_free_term(respheadersr);
erl_free_term(respbodyr);0
erl_free_term(respbodyr);
}
}
}
Expand All @@ -205,11 +209,77 @@ void cnode_run() {

int main(int argc, char **argv) {
cuid = 1;

char *ipaddress;
int port = 8000;
timeout = 10 * CLOCKS_PER_SEC;

int c;
while (1) {
static struct option long_options[] = {
{"verbose", no_argument, &verbose_flag, 1},
{"brief", no_argument, &verbose_flag, 0},
{"ip", required_argument, 0, 'i'},
{"port", required_argument, 0, 'p'},
{"master", required_argument, 0, 'm'},
{"secret", required_argument, 0, 's'},
{"timeout", required_argument, 0, 't'},
{"remote", required_argument, 0, 'r'},
{0, 0, 0, 0}
};
int option_index = 0;
c = getopt_long(argc, argv, "i:p:", long_options, &option_index);
if (c == -1) { break; }
switch (c) {
case 0:
if (long_options[option_index].flag != 0) { break; }
printf ("option %s", long_options[option_index].name);
if (optarg) { printf(" with arg %s", optarg); }
printf("\n");
break;
case 'i':
ipaddress = optarg;
break;
case 'p':
port = atoi(optarg);
break;
case 's':
secret = optarg;
break;
case 'm':
remotenode = optarg;
break;
case 'r':
regproc = optarg;
break;
case 't':
timeout = atoi(optarg) * CLOCKS_PER_SEC;
break;
case '?':
/* getopt_long already printed an error message. */
break;
default:
abort();
}
}
if (ipaddress == NULL) {
ipaddress = "127.0.0.1";
}
if (remotenode == NULL) {
remotenode = "httpdmaster@localhost";
}
if (secret == NULL) {
secret = "supersecret";
}
if (regproc == NULL) {
regproc = "mochevent_handler";
}

pthread_t helper;
pthread_create(&helper, NULL, (void *) cnode_run, NULL);

event_init();
struct evhttp *httpd = evhttp_start("0.0.0.0", 8000);
struct evhttp *httpd = evhttp_start(ipaddress, port);
evhttp_set_gencb(httpd, request_handler, NULL);
event_dispatch();
evhttp_free(httpd);
Expand Down

0 comments on commit 7ef3485

Please sign in to comment.