Skip to content

Commit

Permalink
Simplify the mre construction.
Browse files Browse the repository at this point in the history
  • Loading branch information
erickt committed Jun 3, 2012
1 parent 1d661ac commit 1d8d0ab
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 87 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -5,7 +5,7 @@ test:
rustc --test mre.rc

example-helloworld: all
rustc -L . examples/helloworld/helloworld.rc
rustc -L . examples/helloworld/helloworld.rs

example-blog: all
rustc -L . examples/blog/blog.rc
Expand Down
40 changes: 21 additions & 19 deletions examples/blog/app.rs
Expand Up @@ -10,7 +10,6 @@ type data = {

type app = @{
zmq: zmq::context,
m2: mongrel2::connection,
mre: mre::mre<data>,
es: elasticsearch::client,
mu: mustache::context,
Expand All @@ -23,14 +22,12 @@ fn app() -> app {
err(e) { fail e.to_str() }
};

let m2 = mongrel2::connect(zmq,
"F0D32575-2ABB-4957-BC8B-12DAC8AFF13A",
["tcp://127.0.0.1:9998"],
["tcp://127.0.0.1:9999"]);

// Connect to Elasticsearch, which we'll use as our database.
let es = elasticsearch::connect_with_zmq(zmq, "tcp://localhost:9700");

let middleware = mre::middleware::middleware([
// Create our middleware. We'll use the session middleware so we can
// automatically log a user in based off a session cookie.
let middleware = [
mre::middleware::logger(io::stdout()),
mre::middleware::session(es,
"blog",
Expand All @@ -40,40 +37,45 @@ fn app() -> app {
req.data.session = some(session);
req.data.user = some(user);
}
]);

let mre = mre::mre_builder(zmq, m2, middleware) { ||
{ mut session: none, mut user: none }
};
];


let mu = mustache::context("views", ".mustache");
//
let mre = mre::mre(zmq,
"F0D32575-2ABB-4957-BC8B-12DAC8AFF13A",
["tcp://127.0.0.1:9998"],
["tcp://127.0.0.1:9999"],
middleware,
{ || { mut session: none, mut user: none } });

@{
zmq: zmq,
m2: m2,
mre: mre,
es: es,
mu: mu,

// We store our mustache views in a subdirectory, so we need to
// make our own context to tell mustache where to look.
mu: mustache::context("views", ".mustache"),

// Create a password hasher that uses the pbkdf2 algorithm.
password_hasher: mre::auth::default_pbkdf2_sha1()
}
}

impl app for app {
fn get(regex: str, f: mre::router::handler<data>) {
self.mre.router.add(mre::request::GET, regex, f)
self.mre.get(regex, f)
}

fn post(regex: str, f: mre::router::handler<data>) {
self.mre.router.add(mre::request::POST, regex, f)
self.mre.post(regex, f)
}

fn run() {
self.mre.run();
}

fn term() {
self.m2.term();
self.mre.m2.term();
self.zmq.term();
}
}
13 changes: 0 additions & 13 deletions examples/helloworld/helloworld.rc

This file was deleted.

20 changes: 19 additions & 1 deletion examples/helloworld/helloworld.rs
@@ -1,5 +1,22 @@
use std;
use zmq;
use mre;

// Import some common things into the global namespace.
import result::{result, ok, err};
import zmq::error;
import mre::mre;
import mre::response::response;
import mre::to_bytes::to_bytes;

fn main() {
let mre = mre::mre(
// Create a zeromq context that MRE will use to talk to Mongrel2.
alt zmq::init(1) {
ok(ctx) { ctx }
err(e) { fail e.to_str() }
},

// A UUID for this Mongrel2 backend.
"E4B7CE14-E7F7-43EE-A3E6-DB7B0A0C106F",

Expand All @@ -21,7 +38,7 @@ fn main() {
);

// Route our responses.
mre.router.add(GET, "^/$") { |_req, rep, _m|
mre.get("^/$") { |_req, rep, _m|
rep.reply_html(200u, "
<html>
<body>
Expand All @@ -30,5 +47,6 @@ fn main() {
</html>")
}

// Finally, start the MRE event loop.
mre.run();
}
18 changes: 5 additions & 13 deletions middleware.rs
@@ -1,23 +1,15 @@
import request::request;
import response::response;

type wrapper<T> = fn@(@request<T>, @response);
type middleware<T> = fn@(@request<T>, @response);

type middleware<T> = {
wrappers: [wrapper<T>],
};

fn middleware<T>(wrappers: [wrapper<T>]) -> middleware<T> {
{ wrappers: wrappers }
}

impl middleware<T> for middleware<T> {
impl middleware<T> for [middleware<T>] {
fn wrap(req: @request<T>, rep: @response) {
self.wrappers.iter { |wrapper| wrapper(req, rep); }
self.iter { |middleware| middleware(req, rep); }
}
}

fn logger<T: copy>(logger: io::writer) -> wrapper<T> {
fn logger<T: copy>(logger: io::writer) -> middleware<T> {
{ |req: @request<T>, rep: @response|
let old_end = rep.end;
rep.end = { ||
Expand Down Expand Up @@ -55,7 +47,7 @@ fn session<T>(es: elasticsearch::client,
user_index: str,
cookie_name: str,
f: fn@(@request<T>, session::session, user::user))
-> wrapper<T> {
-> middleware<T> {
{ |req: @request<T>, rep: @response|
req.cookies.find(cookie_name).iter { |cookie|
alt session::find(es, session_index, cookie.value) {
Expand Down
90 changes: 50 additions & 40 deletions mre.rs
Expand Up @@ -10,54 +10,28 @@ import middleware::middleware;

import to_bytes::to_bytes;

type mre<T> = {
zmq: zmq::context,
type mre<T> = @{
m2: mongrel2::connection,
router: router::router<T>,
middleware: middleware::middleware<T>,
mk_data: fn@() -> T,
middleware: [middleware<T>],
data: fn@() -> T,
};

fn mre_builder<T: copy>(zmq: zmq::context,
m2: mongrel2::connection,
middleware: middleware::middleware<T>,
mk_data: fn@() -> T) -> mre<T> {
{
zmq: zmq,
m2: m2,
router: router::router(),
middleware: middleware,
mk_data: mk_data,
}
}

#[doc = "
Helper function to abstract away some of the boilerplate code.
"]
fn mre<T: copy>(sender_id: str,
fn mre<T: copy>(zmq: zmq::context,
sender_id: str,
req_addrs: [str],
rep_addrs: [str],
middleware: [middleware::wrapper<T>],
mk_data: fn@() -> T) -> mre<T> {
// First write some boilerplate code to create an MRE instance. This
// code really should be abstracted away.
let zmq = alt zmq::init(1) {
ok(ctx) { ctx }
err(e) { fail e.to_str() }
};

let m2 = mongrel2::connect(zmq, sender_id, req_addrs, rep_addrs);

// Create our middleware, which preproceses requests and responses.
// For now we'll just use the logger.
let mw = middleware::middleware(middleware);

// Create our MRE instance. Our middleware may needs to store
// middleware somewhere, so we need to pass in a function that creates
// a fresh per-request data. However, since the logger middleware
// doesn't actually need to store anything, we'll just return a unit
// value.
mre_builder(zmq, m2, mw, mk_data)
middleware: [middleware<T>],
data: fn@() -> T) -> mre<T> {
@{
m2: mongrel2::connect(zmq, sender_id, req_addrs, rep_addrs),
router: router::router(),
middleware: middleware,
data: data
}
}

impl mre<T: copy> for mre<T> {
Expand All @@ -74,7 +48,7 @@ impl mre<T: copy> for mre<T> {

let rep = response::response(self.m2, m2_req);

let req = alt request::request(m2_req, rep, self.mk_data()) {
let req = alt request::request(m2_req, rep, self.data()) {
none {
// Ignore this request if it's malformed.
cont;
Expand All @@ -90,4 +64,40 @@ impl mre<T: copy> for mre<T> {
};
}
}

fn head(regex: str, f: router::handler<T>) {
self.router.add(request::HEAD, regex, f)
}

fn get(regex: str, f: router::handler<T>) {
self.router.add(request::GET, regex, f)
}

fn post(regex: str, f: router::handler<T>) {
self.router.add(request::POST, regex, f)
}

fn put(regex: str, f: router::handler<T>) {
self.router.add(request::PUT, regex, f)
}

fn delete(regex: str, f: router::handler<T>) {
self.router.add(request::DELETE, regex, f)
}

fn trace(regex: str, f: router::handler<T>) {
self.router.add(request::TRACE, regex, f)
}

fn options(regex: str, f: router::handler<T>) {
self.router.add(request::OPTIONS, regex, f)
}

fn connect(regex: str, f: router::handler<T>) {
self.router.add(request::CONNECT, regex, f)
}

fn patch(regex: str, f: router::handler<T>) {
self.router.add(request::PATCH, regex, f)
}
}

0 comments on commit 1d8d0ab

Please sign in to comment.