Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a generic client-server implementation to libextra #10818

Closed
wants to merge 1 commit into from

Conversation

brendanzab
Copy link
Member

This commit adds a generic client-server implementation based in part on Erlang's gen_server 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):

use extra::comm::server::*;

struct Server { value: int }

struct Get;
struct Put(int);

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

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

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

struct Cell {
    priv client: SharedClient<Get, Put, int>,
}

impl Cell {
    fn new(x: int) -> Cell {
        Cell { client: spawn_server::<int, (), Get, Put, int, (), 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:

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);

@brendanzab
Copy link
Member Author

Just to be clear, I'm looking for discussion and critique, not an r+ just yet.

cc. @metajack

@alexcrichton
Copy link
Member

This seems really slick! I'm not sure if we want to continue to expand the horizons of libextra (seeing how we still want to dissolve it), but this is certainly really cool.

One thing I should mention is that in my channel rewrite, SharedPort is going away, but it looks like that only affects the SharedClient structure, so I don't think it'd be too bad.

@brendanzab
Copy link
Member Author

@alexcrichton Yeah, perhaps I could just publish it as a separate lib for now. How would I do SharedClient then?

@alexcrichton
Copy link
Member

Closing due to inactivity, and it sounded like this may want to wait for Chan changes to being internally upgradeable (as it would simplify this API)

flip1995 pushed a commit to flip1995/rust that referenced this pull request Jun 30, 2023
new lint: `drain_collect`

Closes rust-lang#10818.

This adds a new lint that looks for `.drain(..).collect()` and suggests replacing it with `mem::take`.

changelog: [`drain_collect`]: new lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants