mozilla/rust — pull request #10818 by bjz (2013-12-05 07:58:26+00:00)
Title: Add a generic client-server implementation to libextra

This commit adds a generic client-server implementation based in part on Erlang's [gen_server](http://www.erlang.org/doc/man/gen_server.html) module. Here is an example of an implementation of how one could implement the cell example described in _Concurrent Programming in ML_ (Reppy, 1999, pp. 42-45):

~~~rust
use server::*;

struct Server { value: int }

struct Get;
struct Put(int);

impl GenericServer for Server {
fn init(x: int) -> Result {
Ok(Server { value: x })
}

fn handle_call(&mut self, _: Get) -> Reply {
Reply(self.value)
}

fn handle_cast(&mut self, Put(x): Put) -> Reply {
self.value = x; Reply(Continue)
}
}

struct Cell {
priv client: SharedClient,
}

impl Cell {
fn new(x: int) -> Cell {
Cell { client: spawn_server::(x)
.unwrap().into_shared() }
}

fn get(&self) -> int { self.client.call(Get) }
fn put(&self, x: int) { self.client.cast(Put(x)) }
}

impl Clone for Cell {
fn clone(&self) -> Cell {
Cell { client: self.client.clone() }
}
}
~~~

And here is an example of the storage cell in use:

~~~rust
let cell = Cell::new(1);
assert_eq!(cell.get(), 1);
cell.put(2);
assert_eq!(cell.get(), 2);
assert_eq!(cell.get(), 2);

let cell2 = cell.clone();
assert_eq!(cell.get(), 2);
cell2.put(3);
assert_eq!(cell.get(), 3);
assert_eq!(cell2.get(), 3);
~~~