Added an experimental reactor API to hide tokio.

This commit is contained in:
Aaron Weiss 2018-01-08 21:52:56 -05:00
parent de26b75204
commit bbc6b0244d
No known key found for this signature in database
GPG key ID: 047D32DF25DC22EF
3 changed files with 60 additions and 18 deletions

View file

@ -1,12 +1,8 @@
extern crate futures;
extern crate irc; extern crate irc;
extern crate tokio_core;
use std::default::Default; use std::default::Default;
use futures::future;
use irc::error; use irc::error;
use irc::client::prelude::*; use irc::client::prelude::*;
use tokio_core::reactor::Core;
fn main() { fn main() {
let cfg1 = Config { let cfg1 = Config {
@ -17,31 +13,23 @@ fn main() {
}; };
let cfg2 = Config { let cfg2 = Config {
nickname: Some("pickles".to_owned()), nickname: Some("bananas".to_owned()),
server: Some("irc.pdgn.co".to_owned()), server: Some("irc.fyrechat.net".to_owned()),
channels: Some(vec!["#irc-crate".to_owned()]), channels: Some(vec!["#irc-crate".to_owned()]),
use_ssl: Some(true),
..Default::default() ..Default::default()
}; };
let configs = vec![cfg1, cfg2]; let configs = vec![cfg1, cfg2];
// Create an event loop to run the multiple connections on. let mut reactor = IrcReactor::new().unwrap();
let mut reactor = Core::new().unwrap();
let processor_handle = reactor.handle();
for config in configs { for config in configs {
let handle = reactor.handle(); let server = reactor.prepare_server_and_connect(&config).unwrap();
let server = reactor.run(IrcServer::new_future(handle, &config).unwrap()).unwrap();
server.identify().unwrap(); server.identify().unwrap();
reactor.register_server_with_handler(server, process_msg);
processor_handle.spawn(server.stream().for_each(move |message| {
process_msg(&server, message)
}).map_err(|e| Err(e).unwrap()))
} }
// You might instead want to join all the futures and run them directly. reactor.run().unwrap();
reactor.run(future::empty::<(), ()>()).unwrap();
} }
fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> { fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> {

View file

@ -2,6 +2,7 @@
pub mod conn; pub mod conn;
pub mod data; pub mod data;
pub mod reactor;
pub mod server; pub mod server;
pub mod transport; pub mod transport;
@ -29,6 +30,7 @@ pub mod prelude {
//! as well as in the parsed form of received mode commands. //! as well as in the parsed form of received mode commands.
pub use client::data::Config; pub use client::data::Config;
pub use client::reactor::IrcReactor;
pub use client::server::{EachIncomingExt, IrcServer, Server}; pub use client::server::{EachIncomingExt, IrcServer, Server};
pub use client::server::utils::ServerExt; pub use client::server::utils::ServerExt;
pub use proto::{Capability, ChannelExt, Command, Message, NegotiationVersion, Response}; pub use proto::{Capability, ChannelExt, Command, Message, NegotiationVersion, Response};

52
src/client/reactor.rs Normal file
View file

@ -0,0 +1,52 @@
//! A system for creating and managing multiple connections to IRC servers.
use client::data::Config;
use client::server::{IrcServer, IrcServerFuture, Server};
use error;
use proto::Message;
use futures::{Future, Stream};
use futures::future;
use tokio_core::reactor::Core;
pub struct IrcReactor {
inner: Core,
handlers: Vec<Box<Future<Item = (), Error = error::Error>>>,
}
impl IrcReactor {
pub fn new() -> error::Result<IrcReactor> {
Ok(IrcReactor {
inner: Core::new()?,
handlers: Vec::new(),
})
}
pub fn prepare_server<'a>(&mut self, config: &'a Config) -> error::Result<IrcServerFuture<'a>> {
IrcServer::new_future(self.inner.handle(), config)
}
pub fn connect_server(&mut self, future: IrcServerFuture) -> error::Result<IrcServer> {
self.inner.run(future)
}
pub fn prepare_server_and_connect(&mut self, config: &Config) -> error::Result<IrcServer> {
self.prepare_server(config).and_then(|future| self.connect_server(future))
}
pub fn register_server_with_handler<F>(
&mut self, server: IrcServer, handler: F
) where F: Fn(&IrcServer, Message) -> error::Result<()> + 'static {
self.handlers.push(Box::new(server.stream().for_each(move |message| {
handler(&server, message)
})));
}
pub fn run(&mut self) -> error::Result<()> {
let mut handlers = Vec::new();
while let Some(handler) = self.handlers.pop() {
handlers.push(handler);
}
self.inner.run(future::join_all(handlers).map(|_| ()))
}
}