<commit_before>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(
                slot fn $name:ident ( $($at:ty),* );
            )*
/*
            $(
                signal fn $sname:ident ( );
            )*
*/
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }
*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            )*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<commit_msg>revert factorial test and macros<commit_after>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(
                slot fn $name:ident ( $($at:ty),* );
            )*
/*
            $(
                signal fn $sname:ident ( );
            )*
*/
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }

*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            )*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<|endoftext|>


<commit_before>use imgui::{Ui,ImStr, ImString, ImGuiSetCond_Once,ImGuiSelectableFlags,ImVec2};
use lichen::parse::{Env,DefBlock};
use lichen::var::Var;

pub struct AppState {
    pub exit: bool,
    pub open_file: bool,
    pub env: Option<Env>,

    pub edit_block: Option<(String,String)>,
}
impl Default for AppState {
    fn default() -> Self {
        AppState {
            exit: false,
            open_file: true,
            env: None,

            edit_block: None,
        }
    }
}

impl AppState {
    pub fn render (&mut self, ui: &Ui) {
        ui.main_menu_bar(|| {
            ui.menu(im_str!("File"))
                .build(|| {
                    ui.menu_item(im_str!("Open"))
                        .selected(&mut self.open_file)
                        .build();

                    ui.menu_item(im_str!("Exit"))
                        .selected(&mut self.exit)
                        .build();
                });
        });

        let mut edit_block = None;
        if let Some(ref env) = self.env {
            ui.window(im_str!("Environment Parsed"))
                .build(||{
                    ui.tree_node(im_str!("Def Blocks"))
                        .opened(true, ImGuiSetCond_Once)
                        .build(|| {
                            for d in env.def.keys() {
                                if ui.collapsing_header(im_str!("{:?}",d))
                                    .build() {
                                        let block = env.def.get(d).unwrap();
                                        for (k,v) in block.def.iter() {
                                            let info = im_str!("{:}: {:?}",k,v);
                                            if ui_simple_select(info,ui) {
                                                edit_block = Some((d.to_owned(),
                                                                        k.to_owned()));
                                            }
                                        }
                                    }
                            }
                        });

                    ui.tree_node(im_str!("Src Blocks"))
                        .opened(true, ImGuiSetCond_Once)
                        .build(|| {
                            for k in env.src.keys() {
                                if ui.collapsing_header(im_str!("{:?}",k))
                                    .build() {
                                        let block = env.src.get(k).unwrap();
                                        for src in block.src.iter() {
                                            let info = im_str!("{:?}",src);
                                            if ui_simple_select(info,ui) {
                                            }
                                        }
                                    }
                            }
                        });
                });

        }

        if edit_block.is_some() {
            self.edit_block = edit_block;
        }

        self.edit_block(ui);
    }

    pub fn edit_block(&mut self, ui: &Ui) {
        if let Some((ref block,ref key)) = self.edit_block.clone() {
            ui.window(im_str!("Def Block {:}", block))
                .build(|| {
                    ui.text(im_str!("Var Name: {:}",key));
                    if let Some(ref mut env) = self.env {

                        if let Some(mut var) =
                            env.def.get_mut(block).expect("ERROR: Block missing")
                            .def.get_mut(key) {

                                let var_;
                                match var {
                                    &mut Var::Num(ref n) => {
                                        let mut num = n.clone();
                                        ui.input_float(im_str!("Value: {:?}",var), &mut num)
                                            .step(0.125)
                                            .build();
                                        var_ = Var::Num(num);
                                    },
                                    &mut Var::String(ref s) => {
                                        let mut text = ImString::new(s.clone()).unwrap();
                                        text.reserve(1024); // NOTE: reserve arbitrary size
                                        // actual max size might not be this!

                                        ui.input_text(im_str!("Value: {:?}",var), &mut text)
                                            .build();
                                        var_ = Var::String(text.to_string());
                                    },
                                    &mut Var::Bool(ref b) => {
                                        let mut b = b.clone();
                                        ui.checkbox(im_str!("Value: {:?}",var), &mut b);
                                        var_ = Var::Bool(b);
                                    },
                                    _ => {
                                        ui.text(im_str!("Value: {:?}",var));
                                        var_ = var.clone();
                                    }
                                }

                                *var = var_;
                            }
                    }
                })
        }
    }
}

fn ui_simple_select(info: &ImStr, ui: &Ui) -> bool {
    ui.selectable(info,
                  false,
                  ImGuiSelectableFlags::empty(),
                  ImVec2::new(0.0, 0.0))
}
<commit_msg>remove unused<commit_after>use imgui::{Ui,ImStr, ImString, ImGuiSetCond_Once,ImGuiSelectableFlags,ImVec2};
use lichen::parse::{Env};
use lichen::var::Var;

pub struct AppState {
    pub exit: bool,
    pub open_file: bool,
    pub env: Option<Env>,

    pub edit_block: Option<(String,String)>,
}
impl Default for AppState {
    fn default() -> Self {
        AppState {
            exit: false,
            open_file: true,
            env: None,

            edit_block: None,
        }
    }
}

impl AppState {
    pub fn render (&mut self, ui: &Ui) {
        ui.main_menu_bar(|| {
            ui.menu(im_str!("File"))
                .build(|| {
                    ui.menu_item(im_str!("Open"))
                        .selected(&mut self.open_file)
                        .build();

                    ui.menu_item(im_str!("Exit"))
                        .selected(&mut self.exit)
                        .build();
                });
        });

        let mut edit_block = None;
        if let Some(ref env) = self.env {
            ui.window(im_str!("Environment Parsed"))
                .build(||{
                    ui.tree_node(im_str!("Def Blocks"))
                        .opened(true, ImGuiSetCond_Once)
                        .build(|| {
                            for d in env.def.keys() {
                                if ui.collapsing_header(im_str!("{:?}",d))
                                    .build() {
                                        let block = env.def.get(d).unwrap();
                                        for (k,v) in block.def.iter() {
                                            let info = im_str!("{:}: {:?}",k,v);
                                            if ui_simple_select(info,ui) {
                                                edit_block = Some((d.to_owned(),
                                                                        k.to_owned()));
                                            }
                                        }
                                    }
                            }
                        });

                    ui.tree_node(im_str!("Src Blocks"))
                        .opened(true, ImGuiSetCond_Once)
                        .build(|| {
                            for k in env.src.keys() {
                                if ui.collapsing_header(im_str!("{:?}",k))
                                    .build() {
                                        let block = env.src.get(k).unwrap();
                                        for src in block.src.iter() {
                                            let info = im_str!("{:?}",src);
                                            if ui_simple_select(info,ui) {
                                            }
                                        }
                                    }
                            }
                        });
                });

        }

        if edit_block.is_some() {
            self.edit_block = edit_block;
        }

        self.edit_block(ui);
    }

    pub fn edit_block(&mut self, ui: &Ui) {
        if let Some((ref block,ref key)) = self.edit_block.clone() {
            ui.window(im_str!("Def Block {:}", block))
                .build(|| {
                    ui.text(im_str!("Var Name: {:}",key));
                    if let Some(ref mut env) = self.env {

                        if let Some(mut var) =
                            env.def.get_mut(block).expect("ERROR: Block missing")
                            .def.get_mut(key) {

                                let var_;
                                match var {
                                    &mut Var::Num(ref n) => {
                                        let mut num = n.clone();
                                        ui.input_float(im_str!("Value: {:?}",var), &mut num)
                                            .step(0.125)
                                            .build();
                                        var_ = Var::Num(num);
                                    },
                                    &mut Var::String(ref s) => {
                                        let mut text = ImString::new(s.clone()).unwrap();
                                        text.reserve(1024); // NOTE: reserve arbitrary size
                                        // actual max size might not be this!

                                        ui.input_text(im_str!("Value: {:?}",var), &mut text)
                                            .build();
                                        var_ = Var::String(text.to_string());
                                    },
                                    &mut Var::Bool(ref b) => {
                                        let mut b = b.clone();
                                        ui.checkbox(im_str!("Value: {:?}",var), &mut b);
                                        var_ = Var::Bool(b);
                                    },
                                    _ => {
                                        ui.text(im_str!("Value: {:?}",var));
                                        var_ = var.clone();
                                    }
                                }

                                *var = var_;
                            }
                    }
                })
        }
    }
}

fn ui_simple_select(info: &ImStr, ui: &Ui) -> bool {
    ui.selectable(info,
                  false,
                  ImGuiSelectableFlags::empty(),
                  ImVec2::new(0.0, 0.0))
}
<|endoftext|>


<commit_before>use std::thread::{self,Thread,Builder};
use std::sync::mpsc::{self,channel,Sender,Receiver};
use std::collections::HashMap;

use messages::{Acl, Command, Tag};

#[derive(Clone)]
pub enum Message {
  Subscribe(Tag, Sender<Message>),
  SubscribeOk,
  Msg(Tag, Command)
}

pub fn start_bus() -> Sender<Message> {
  let (tx,rx) = channel::<Message>();

  thread::spawn(move|| {
    let mut bus = Bus {
      rx: rx,
      senders: HashMap::new()
    };

    bus.loop_message();
  });
  tx
}

struct Bus {
  rx: Receiver<Message>,
  senders: HashMap<Tag, Vec<Sender<Message>>>
}

impl Bus {
  fn loop_message(&mut self) {
    loop {
      if ! self.handle_message() {
        break;
      }
    }
  }

  fn handle_message(&mut self) -> bool {
    match &self.rx.recv() {
      &Ok(Message::Subscribe(ref tag, ref tx)) => {
        self.subscribe(tag, tx);
        println!("SUBSCRIBED");
        return true;
      },
      &Ok(Message::Msg(ref t, ref c)) => {
        println!("GOT MSG");
        if let &Some(v) = &self.senders.get(&t) {
          println!("GOT MSG 2");
          for tx in v {
            println!("GOT MSG 3");
            tx.send(Message::Msg(t.clone(), c.clone()));
          }
        }
        return true;
      },
      &Err(_) => {
        println!("the bus's channel is closed, exiting");
        return false;
      }
      &Ok(_) => {
        println!("invalid message");
        // FIXME: maybe we should not stop if there's an invalid message
        return false;
      }
    }
  }

  fn subscribe(&mut self, t: &Tag, tx: &Sender<Message>) {
    println!("X");
    if ! &self.senders.contains_key(t) {
      let mut v = Vec::new();
      let t2 = t.clone();
      &self.senders.insert(t2, v);
      println!("Y");
    }
    if let Some(ref mut v) = self.senders.get_mut(t) {
      v.push(tx.clone());
      tx.send(Message::SubscribeOk);
      println!("Z");
    }
  }
}

#[test]
fn bus_test() {
  let tx = start_bus();

  let (tx2,rx2) = channel();
  println!("AA");
  tx.send(Message::Subscribe(Tag::AddAcl, tx2));
  println!("BB");

  if let Ok(Message::SubscribeOk) = rx2.recv() {
    println!("successfully subscribed");
    let tag = Tag::AddAcl;
    let command = Command::AddAcl(
      Acl {
        app_id: String::new() + "app_e74eb0d4-e01a-4a09-af46-7ecab7157d32",
        hostname: String::new() + "cltdl.fr",
        path_begin: String::new() + ""
      }
    );
    tx.send(Message::Msg(tag.clone(), command.clone()));

    if let Ok(Message::Msg(t, c)) = rx2.recv() {
      assert_eq!(t, tag);
      assert_eq!(c, command);
    } else {
      assert!(false);
    }
  } else {
    assert!(false);
  }
}
<commit_msg>Add Debug instance for Message<commit_after>use std::thread::{self,Thread,Builder};
use std::sync::mpsc::{self,channel,Sender,Receiver};
use std::collections::HashMap;

use messages::{Acl, Command, Tag};

#[derive(Clone)]
pub enum Message {
  Subscribe(Tag, Sender<Message>),
  SubscribeOk,
  Msg(Tag, Command)
}

impl Message {
  pub fn display(&self) {
      match self {
        &Message::Subscribe(_, _) => println!("Subscribe"),
        &Message::SubscribeOk => println!("SubscribeOk"),
        &Message::Msg(ref t, ref c) => {
          println!("{:?}", t);
          println!("{:?}", c)
        }
      }
  }
}

pub fn start_bus() -> Sender<Message> {
  let (tx,rx) = channel::<Message>();

  thread::spawn(move|| {
    let mut bus = Bus {
      rx: rx,
      senders: HashMap::new()
    };

    bus.loop_message();
  });
  tx
}

struct Bus {
  rx: Receiver<Message>,
  senders: HashMap<Tag, Vec<Sender<Message>>>
}

impl Bus {
  fn loop_message(&mut self) {
    loop {
      if ! self.handle_message() {
        break;
      }
    }
  }

  fn handle_message(&mut self) -> bool {
    match &self.rx.recv() {
      &Ok(Message::Subscribe(ref tag, ref tx)) => {
        self.subscribe(tag, tx);
        println!("SUBSCRIBED");
        return true;
      },
      &Ok(Message::Msg(ref t, ref c)) => {
        println!("GOT MSG");
        if let &Some(v) = &self.senders.get(&t) {
          println!("GOT MSG 2");
          for tx in v {
            println!("GOT MSG 3");
            tx.send(Message::Msg(t.clone(), c.clone()));
          }
        }
        return true;
      },
      &Err(_) => {
        println!("the bus's channel is closed, exiting");
        return false;
      }
      &Ok(_) => {
        println!("invalid message");
        // FIXME: maybe we should not stop if there's an invalid message
        return false;
      }
    }
  }

  fn subscribe(&mut self, t: &Tag, tx: &Sender<Message>) {
    println!("X");
    if ! &self.senders.contains_key(t) {
      let mut v = Vec::new();
      let t2 = t.clone();
      &self.senders.insert(t2, v);
      println!("Y");
    }
    if let Some(ref mut v) = self.senders.get_mut(t) {
      v.push(tx.clone());
      tx.send(Message::SubscribeOk);
      println!("Z");
    }
  }
}

#[test]
fn bus_test() {
  let tx = start_bus();

  let (tx2,rx2) = channel();
  println!("AA");
  tx.send(Message::Subscribe(Tag::AddAcl, tx2));
  println!("BB");

  if let Ok(Message::SubscribeOk) = rx2.recv() {
    println!("successfully subscribed");
    let tag = Tag::AddAcl;
    let command = Command::AddAcl(
      Acl {
        app_id: String::new() + "app_e74eb0d4-e01a-4a09-af46-7ecab7157d32",
        hostname: String::new() + "cltdl.fr",
        path_begin: String::new() + ""
      }
    );
    tx.send(Message::Msg(tag.clone(), command.clone()));

    if let Ok(Message::Msg(t, c)) = rx2.recv() {
      assert_eq!(t, tag);
      assert_eq!(c, command);
    } else {
      assert!(false);
    }
  } else {
    assert!(false);
  }
}
<|endoftext|>


<commit_before>use papers::Papers;

use futures::future;
use futures::{Future, Stream};
use hyper::server::{Http, NewService};
use slog;
use slog::{Filter, DrainExt, Level};
use slog_term;
use tokio_core;

pub fn is_debug_active() -> bool {
    match ::std::env::var("PAPERS_LOG_LEVEL") {
        Ok(ref level) if level.contains("debug") => true,
        _ => false,
    }
}

pub struct Server {
    auth: String,
    port: i32,
    logger: slog::Logger,
}

impl Server {
    pub fn new() -> Server {
        let minimum_level = if is_debug_active() {
            Level::Debug
        } else {
            Level::Info
        };
        let drain = slog_term::streamer().full().build().fuse();
        let drain = Filter::new(drain,
                                move |record| record.level().is_at_least(minimum_level));
        let logger = slog::Logger::root(drain, o!());
        let bearer = ::std::env::var("PAPERS_BEARER").unwrap_or_else(|_| "".to_string());
        Server {
            auth: bearer,
            port: 8008,
            logger: logger,
        }
    }

    pub fn with_auth(self, auth: String) -> Server {
        Server { auth, ..self }
    }

    pub fn with_port(self, port: i32) -> Server {
        Server { port, ..self }
    }

    pub fn start(self) {
        let mut core = tokio_core::reactor::Core::new().unwrap();
        let papers_service = Papers::new(core.remote(), self.logger.new(o!()), self.auth);
        let socket_addr = format!("0.0.0.0:{:?}", self.port).parse().unwrap();
        let handle = core.handle();
        let listener = tokio_core::net::TcpListener::bind(&socket_addr, &core.handle()).unwrap();
        let work = listener
            .incoming()
            .for_each(|(tcp_stream, socket_addr)| {
                          Http::new().bind_connection(&handle,
                                                      tcp_stream,
                                                      socket_addr,
                                                      papers_service.new_service().unwrap());
                          future::ok(())
                      });
        core.run(future::ok(info!(self.logger.new(o!("version" => env!("CARGO_PKG_VERSION"))),
                                  "Server started on http://{}",
                                  socket_addr))
                         .and_then(|_| work))
            .unwrap()
    }
}

impl ::std::default::Default for Server {
    fn default() -> Server {
        Server::new()
    }
}
<commit_msg>✨ Get the max_assets_per_document env var<commit_after>use papers::Papers;

use futures::future;
use futures::{Future, Stream};
use hyper::server::{Http, NewService};
use slog;
use slog::{Filter, DrainExt, Level};
use slog_term;
use tokio_core;

pub fn is_debug_active() -> bool {
    match ::std::env::var("PAPERS_LOG_LEVEL") {
        Ok(ref level) if level.contains("debug") => true,
        _ => false,
    }
}

fn max_assets_per_document(logger: &slog::Logger) -> u8 {
    let default = 20;
    match ::std::env::var("PAPERS_MAX_ASSETS_PER_DOCUMENT").map(|max| max.parse()) {
        Ok(Ok(max)) => max,
        Ok(Err(_)) => {
            warn!(logger, "Unable to parse PAPERS_MAX_ASSETS_PER_DOCUMENT environmental variable");
            default
        },
        _ => default,
    }
}

pub struct Server {
    auth: String,
    port: i32,
    logger: slog::Logger,
    max_assets_per_document: u8,
}

impl Server {
    pub fn new() -> Server {
        let minimum_level = if is_debug_active() {
            Level::Debug
        } else {
            Level::Info
        };
        let drain = slog_term::streamer().full().build().fuse();
        let drain = Filter::new(drain,
                                move |record| record.level().is_at_least(minimum_level));
        let logger = slog::Logger::root(drain, o!());
        let bearer = ::std::env::var("PAPERS_BEARER").unwrap_or_else(|_| "".to_string());
        let max_assets_per_document = max_assets_per_document(&logger);
        Server {
            auth: bearer,
            port: 8008,
            logger: logger,
            max_assets_per_document,
        }
    }

    pub fn with_auth(self, auth: String) -> Server {
        Server { auth, ..self }
    }

    pub fn with_port(self, port: i32) -> Server {
        Server { port, ..self }
    }

    pub fn start(self) {
        let mut core = tokio_core::reactor::Core::new().unwrap();
        let papers_service = Papers::new(core.remote(), self.logger.new(o!()), self.auth);
        let socket_addr = format!("0.0.0.0:{:?}", self.port).parse().unwrap();
        let handle = core.handle();
        let listener = tokio_core::net::TcpListener::bind(&socket_addr, &core.handle()).unwrap();
        let work = listener
            .incoming()
            .for_each(|(tcp_stream, socket_addr)| {
                          Http::new().bind_connection(&handle,
                                                      tcp_stream,
                                                      socket_addr,
                                                      papers_service.new_service().unwrap());
                          future::ok(())
                      });
        core.run(future::ok(info!(self.logger.new(o!("version" => env!("CARGO_PKG_VERSION"))),
                                  "Server started on http://{}",
                                  socket_addr))
                         .and_then(|_| work))
            .unwrap()
    }
}

impl ::std::default::Default for Server {
    fn default() -> Server {
        Server::new()
    }
}
<|endoftext|>


<commit_before>
use std::sync::{Arc, RwLock};
use std::io;
use std::io::{Error, ErrorKind};
use mio::{Event, Events, Token};
use context::ServerContext;
use serialize;

//must be less than this
pub const SERVERTOKEN: Token = Token(1000);

//#[derive(Clone)]
pub struct Server<T: serialize::MessageHandler + Sized> {
    _token: Token,
    _events: Events,

    //the refcell used betten than raw trait
    //it can callback the mut function when needed
    _handle: Arc<RwLock<T>>,
}

impl<T: serialize::MessageHandler + Sized> Clone for Server<T> {
    fn clone(&self) -> Self {
        Server {
            _token: self._token,
            _events: Events::with_capacity(self._events.capacity()),
            _handle: self._handle.clone(),
        }
    }
}

impl<T: serialize::MessageHandler + Sized> Server<T> {
    pub fn new(handler: T) -> Server<T> {
        let ptr = Arc::new(RwLock::new(handler));

        return Server {
                   _token: SERVERTOKEN,
                   _events: Events::with_capacity(1024),
                   _handle: ptr,
               };
    }

    pub fn run(&mut self, ctx: &ServerContext) -> io::Result<()> {
        ctx.register_read(self._token)?;
        //println!("run {:?} {:?}", self._token, self._listener);
        loop {
            println!("start to poll");
            let size = ctx.poll_once(&mut self._events)?;
            println!("poll size{}", size);

            for i in 0..size {
                let event_op = self._events.get(i);
                if let Some(event) = event_op {
                    self.on_event(ctx, &event);
                } else {
                    println!("errror event");
                    break;
                }
            }
        }
    }

    fn on_event(&mut self, ctx: &ServerContext, event: &Event) {
        let ready = event.readiness();
        let token = event.token();
        if ready.is_error() {
            ctx.remove_client(token);
            println!("error event recv");
            return;
        }

        let mut vec: Vec<Token> = vec![];

        if ready.is_readable() {
            if token == self._token {
                println!("new client connected");
                self.on_accept(ctx);
            } else {
                println!("forward read, token={:?}", token);
                match self.forward_readable(token, ctx) {
                    Err(_) => {
                        vec.push(token);
                    }
                    Ok(_) => {}
                }
            }
        } //end

        if ready.is_writable() {
            let mut conns = ctx._conns.write().unwrap();
            let client_op = conns.get_mut(token);
            if let Some(mut c) = client_op {
                println!("client write event, token={:?}", token);
                c.on_write()
                    .unwrap_or_else(|_| { vec.push(c.get_token()); });
            }
        }

        for token in vec {
            ctx.remove_client(token);
        }
    }

    fn on_accept(&mut self, ctx: &ServerContext) {
        loop {
            let accept_result = ctx._listener.read().unwrap().accept();
            //println!("get one client");
            let client = match accept_result {
                Ok((c, _)) => c,
                Err(e) => {
                    if e.kind() != ErrorKind::WouldBlock {
                        println!("accept error");
                    }
                    //println!("accept wuld block, {:?}", e);
                    return;
                }
            };
            let token = ctx.available_token(client);
            if let Some(t) = token {
                println!("client added:......");
                ctx.register_token(t).expect("register client failed");
            } else {
                println!("no available token found");
            }
        }
    }

    fn forward_readable(&mut self, token: Token, ctx: &ServerContext) -> io::Result<()> {
        let mut conns = ctx._conns.write().unwrap();
        let client_op = conns.get_mut(token);
        let client = match client_op {
            Some(expr) => expr,
            None => {
                println!("no client got:{:?}", token);
                return Err(Error::new(ErrorKind::InvalidData, "invlid token"));
            }
        };

        loop {
            let read_result = client.on_read();
            if let Ok(read_op) = read_result {
                if let Some(message) = read_op {
                    let rc_message = Arc::new(message);
                    println!("client send message start..");
                    // Queue up a write for all connected clients.
                    let handler = self._handle.read().unwrap();
                    handler.on_message_received(&client, &rc_message)?
                    //client.send_message(rc_message.clone());
                } else {
                    println!("forward read: no message got");
                    break;
                }
            } else {
                println!("forward read: read failed");
                return Err(Error::new(ErrorKind::InvalidData, "read failed"));
            }
        }
        Ok(())
    }
}
<commit_msg>Update server.rs<commit_after>
use std::sync::{Arc};
use std::io;
use std::io::{Error, ErrorKind};
use mio::{Event, Events, Token, Evented};
use mio::net::TcpListener;
use mio::unix::UnixReady;
use context::Context;
use serialize;
use poll;

//must be less than this
pub const SERVERTOKEN: Token = Token(1000_000);

//#[derive(Clone)]
pub struct Server {
    _token: Token,
    _events: Events,

    _listener:TcpListener,
    _poller:poll::Poller,
}

/*
impl<T: serialize::MessageHandler + Sized> Clone for Server<T> {
    fn clone(&self) -> Self {
        Server {
            _token: self._token,
            _events: Events::with_capacity(self._events.capacity()),
            _handle: self._handle.clone(),
            _listener:self._listener.try_clone(),
            _poller:poll::Poller.clone(),
        }
    }
} */

impl Server {
    pub fn new(listener:TcpListener) -> Option<Self> {
        let p = poll::Poller::new();
        if let Ok(poll) = p {
            return Some(Server {
                _token: SERVERTOKEN,
                _events: Events::with_capacity(1024),
                _listener:listener,
                _poller:poll,
            });
        }
        None
    }

    pub fn poll_once(&mut self) -> io::Result<usize> {
        self._poller.poll_once(&mut self._events)
    }

    pub fn unregister_token<T>(&self, ctx:&Context<T>, token:Token)->io::Result<()>
        where T:serialize::MessageHandler + Sized {

        let clients = ctx._conns.read().unwrap();
        let client = clients.get(token);
        if let Some(c) = client {
            return self._poller.deregister(&c._stream);
        }

        Ok(())
    }

    #[allow(dead_code)]
    pub fn unregister<E: ?Sized>(&self, handle:&E)->io::Result<()>
        where E:Evented {
        self._poller.deregister(handle)
    }

    pub fn register_read(&self, token: Token) -> io::Result<()> {
        //Listener token will be registered into every poller instance
        //in every server=====, in case of thread panic
        self._poller.register_read(&self._listener, token)
    }

    pub fn run<T>(&mut self, ctx: &Context<T>)  -> io::Result<()>
        where T: serialize::MessageHandler + Sized {

        println!("--------start to register {:?}", self._token);
        self.register_read(self._token)?;
        println!("+++++run {:?} {:?}", self._token, self._listener);
        loop {
            println!("start to poll");
            let size = self.poll_once()?;
            println!("poll size{}", size);

            for i in 0..size {
                let event_op = self._events.get(i);
                if let Some(event) = event_op {
                    self.on_event(ctx, &event);
                } else {
                    println!("errror event");
                    break;
                }
            }//end for?
        }
    }

    pub fn register_token<T>(&mut self, ctx:&Context<T>, token: Token) -> io::Result<()>
        where T: serialize::MessageHandler + Sized {
        let clients = ctx._conns.read().unwrap();

        if let Some(c) = clients.get(token) {
            c.register(&mut self._poller)?;
            return Ok(());
        }

        Err(Error::new(ErrorKind::InvalidInput, "Invalid token"))
    }

    fn on_event<T>(&mut self, ctx: &Context<T>, event: &Event)
        where T : serialize::MessageHandler + Sized {
        let ready = UnixReady::from(event.readiness());
        let token = event.token();
        if ready.is_error() {
            if let Err(e) = self.unregister_token(ctx, token) {
                println!("-----------------------{:?}", e);
            }

            ctx.remove_client(token);
            println!("error event recv");
            return;
        }

        let mut vec: Vec<Token> = vec![];
        if ready.is_readable() {
            if token == self._token {
                println!("new client connected");
                self.on_accept(ctx);
            } else {
                println!("forward read, token={:?}", token);
                match self.dispatch_read(token, ctx) {
                    Err(_) => {
                        vec.push(token);
                    }
                    Ok(_) => {}
                }
            }
        } //end

        if ready.is_writable() {
            let mut conns = ctx._conns.write().unwrap();
            let client_op = conns.get_mut(token);
            if let Some(mut c) = client_op {
                println!("client write event, token={:?}", token);
                c.on_write()
                    .unwrap_or_else(|_| { vec.push(c.get_token()); });
            }
        }

        for token in vec {
            if let Err(e) = self.unregister_token(ctx, token) {
                println!("-----------------------{:?}", e);
            }

            ctx.remove_client(token);
        }
    }

    fn on_accept<T>(&mut self, ctx: &Context<T>)
        where T : serialize::MessageHandler + Sized {
        loop {
            let accept_result = self._listener.accept();
            //println!("get one client");
            let client = match accept_result {
                Ok((c, _)) => c,
                Err(e) => {
                    if e.kind() != ErrorKind::WouldBlock {
                        println!("accept error");
                    }
                    //println!("accept wuld block, {:?}", e);
                    return;
                }
            };
            let token = ctx.available_token(client);
            if let Some(t) = token {
                println!("client added:......");
                self.register_token(ctx, t).expect("register client failed");
            } else {
                println!("no available token found");
            }
        }
    }

    fn dispatch_read<T>(&mut self, token: Token, ctx: &Context<T>) -> io::Result<()>
        where T : serialize::MessageHandler + Sized {
        let mut conns = ctx._conns.write().unwrap();
        let client_op = conns.get_mut(token);
        let client = match client_op {
            Some(expr) => expr,
            None => {
                println!("no client got:{:?}", token);
                return Err(Error::new(ErrorKind::InvalidData, "invlid token"));
            }
        };

        loop {
            let read_result = client.on_read();
            if let Ok(read_op) = read_result {
                if let Some(message) = read_op {
                    let rc_message = Arc::new(message);
                    println!("client send message start..");
                    // Queue up a write for all connected clients.
                    let handler = ctx._handle.read().unwrap();
                    handler.on_message_received(&client, &rc_message)?
                    //client.send_message(rc_message.clone());
                } else {
                    println!("forward read: no message got");
                    break;
                }
            } else {
                println!("forward read: read failed");
                return Err(Error::new(ErrorKind::InvalidData, "read failed"));
            }
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::io::{Listener, Acceptor};
use std::collections::HashMap;
use std::str;
use std::vec::Vec;
use std::io::net::tcp::TcpListener;
use util;

pub fn start_server() {

    let mut acceptor = TcpListener::bind("127.0.0.1", 9876).listen().unwrap();
    println!("listening started, ready to accept");
    let opt_stream = acceptor.accept();
    let mut buffer = [0u8, ..4096];
    let mut stream = opt_stream.unwrap();
    loop {
        let read_bytes = stream.read(buffer).unwrap();
        let command = str::from_utf8(buffer.slice(0, read_bytes)).unwrap().trim();

        if command.starts_with("checksum") {
            let file_path = command.replace("checksum ", "");
            stream.write(b"OK ");
            stream.write(util::get_file_checksum(&Path::new(file_path)).as_bytes());
            stream.write(b"\n");
        } else if command.starts_with("metadata") {
            let dir_path = command.replace("metadata ", "");
            let mut file_map = HashMap::<(u64, u64), Vec<String>>::new();
            util::examine_files(&Path::new(dir_path), &mut file_map);
            for (key, values) in file_map.iter() {
                for value in values.iter() {
                    let &(size, mod_date) = key;
                    stream.write(size.to_string().as_bytes());
                    stream.write(b" ");
                    stream.write(mod_date.to_string().as_bytes());
                    stream.write(b" ");
                    stream.write(value.as_bytes());
                    stream.write_u8(0u8);
                    stream.write(b"\n");
                }
            }
        }
        else if command == "exit" {
            break;
        } else {
            stream.write(b"ERR Invalid command \"");
            stream.write(command.as_bytes());
            stream.write(b"\"\n");
        }
    }
}

<commit_msg>Replace TCP server in favour of stdin / stdout<commit_after>use std::io::stdio;
use std::collections::HashMap;
use std::str;
use std::vec::Vec;
use util;

pub fn start_server() {

    manage_client(&mut stdio::stdin_raw(), &mut stdio::stdout_raw());
}

fn manage_client(input: &mut Reader, output: &mut Writer) {

    let mut buffer = [0u8, ..4096];

    loop {
        let read_bytes = input.read(buffer).unwrap();
        let command = str::from_utf8(buffer.slice(0, read_bytes)).unwrap().trim();

        if command.starts_with("checksum") {
            let file_path = command.replace("checksum ", "");
            output.write(b"OK ");
            output.write(util::get_file_checksum(&Path::new(file_path)).as_bytes());
            output.write(b"\n");
        } else if command.starts_with("metadata") {
            let dir_path = command.replace("metadata ", "");
            let mut file_map = HashMap::<(u64, u64), Vec<String>>::new();
            util::examine_files(&Path::new(dir_path), &mut file_map);
            output.write(b"OK START\n");
            for (key, values) in file_map.iter() {
                for value in values.iter() {
                    let &(size, mod_date) = key;
                    output.write(size.to_string().as_bytes());
                    output.write(b" ");
                    output.write(mod_date.to_string().as_bytes());
                    output.write(b" ");
                    output.write(value.as_bytes());
                    output.write_u8(0u8);
                    output.write(b"\n");
                }
            }
            output.write(b"END\n");
        }
        else if command == "exit" {
            break;
        } else {
            output.write(b"ERR Invalid command \"");
            output.write(command.as_bytes());
            output.write(b"\"\n");
        }
    }

}
<|endoftext|>


<commit_before>use std::env;
use std::io::ErrorKind;
use std::process;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
use std::net::SocketAddr;
use hex;
use time;

use byteorder::{LittleEndian, WriteBytesExt};

use mio::net::UdpSocket;
use mio::{Events, Poll, PollOpt, Ready, Token};
use mio_extras::timer::Timer;

use config;
use config::ServerConfig;
use kms;
use key::{LongTermKey, OnlineKey};
use merkle::MerkleTree;
use {Error, RtMessage, Tag};
use {MIN_REQUEST_LENGTH, VERSION};

macro_rules! check_ctrlc {
    ($keep_running:expr) => {
        if !$keep_running.load(Ordering::Acquire) {
            warn!("Ctrl-C caught, exiting...");
            return true;
        }
    }
}

const MESSAGE: Token = Token(0);
const STATUS: Token = Token(1);

pub struct Server {
    config: Box<ServerConfig>,
    online_key: OnlineKey,
    cert_bytes: Vec<u8>,

    response_counter: AtomicUsize,
    num_bad_requests: u64,

    socket: UdpSocket,
    fake_client_socket: UdpSocket,
    keep_running: Arc<AtomicBool>,
    poll_duration: Option<Duration>,
    timer: Timer<()>,
    poll: Poll,
    events: Events,
    merkle: MerkleTree,
    requests: Vec<(Vec<u8>, SocketAddr)>,
    buf: [u8; 65_536],

    public_key: String,
}

impl Server {
    pub fn new(config: Box<ServerConfig>) -> Server {

        let mut online_key = OnlineKey::new();
        let public_key: String;

        let cert_bytes = {
            let seed = kms::load_seed(&config).unwrap();
            let mut long_term_key = LongTermKey::new(&seed);
            public_key = hex::encode(long_term_key.public_key());

            long_term_key.make_cert(&online_key).encode().unwrap()
        };

        let response_counter = AtomicUsize::new(0);
        let keep_running = Arc::new(AtomicBool::new(true));

        let sock_addr = config.socket_addr().expect("");
        let socket = UdpSocket::bind(&sock_addr).expect("failed to bind to socket");
        let fake_client_socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap()).unwrap();

        let poll_duration = Some(Duration::from_millis(100));

        let mut timer: Timer<()> = Timer::default();
        //timer.set_timeout(config.status_interval(), ());

        let poll = Poll::new().unwrap();
        poll.register(&socket, MESSAGE, Ready::readable(), PollOpt::edge())
            .unwrap();
        //poll.register(&timer, STATUS, Ready::readable(), PollOpt::edge())
        //    .unwrap();

        let mut merkle = MerkleTree::new();
        let mut requests = Vec::with_capacity(config.batch_size() as usize);

        Server {
            config,
            online_key,
            cert_bytes,

            response_counter,
            num_bad_requests: 0,
            socket,
            fake_client_socket,
            keep_running,
            poll_duration,
            timer,
            poll,
            events: Events::with_capacity(32),
            merkle,
            requests,
            buf: [0u8; 65_536],

            public_key
        }

    }

    pub fn get_keep_running(&self) -> Arc<AtomicBool> {
        return self.keep_running.clone()
    }

    // extract the client's nonce from its request
    fn nonce_from_request(buf: &[u8], num_bytes: usize) -> Result<&[u8], Error> {
        if num_bytes < MIN_REQUEST_LENGTH as usize {
            return Err(Error::RequestTooShort);
        }

        let tag_count = &buf[..4];
        let expected_nonc = &buf[8..12];
        let expected_pad = &buf[12..16];

        let tag_count_is_2 = tag_count == [0x02, 0x00, 0x00, 0x00];
        let tag1_is_nonc = expected_nonc == Tag::NONC.wire_value();
        let tag2_is_pad = expected_pad == Tag::PAD.wire_value();

        if tag_count_is_2 && tag1_is_nonc && tag2_is_pad {
            Ok(&buf[0x10..0x50])
        } else {
            Err(Error::InvalidRequest)
        }
    }

    fn make_response(srep: &RtMessage, cert_bytes: &[u8], path: &[u8], idx: u32) -> RtMessage {
        let mut index = [0; 4];
        (&mut index as &mut [u8])
            .write_u32::<LittleEndian>(idx)
            .unwrap();

        let sig_bytes = srep.get_field(Tag::SIG).unwrap();
        let srep_bytes = srep.get_field(Tag::SREP).unwrap();

        let mut response = RtMessage::new(5);
        response.add_field(Tag::SIG, sig_bytes).unwrap();
        response.add_field(Tag::PATH, path).unwrap();
        response.add_field(Tag::SREP, srep_bytes).unwrap();
        response.add_field(Tag::CERT, cert_bytes).unwrap();
        response.add_field(Tag::INDX, &index).unwrap();

        response
    }

    pub fn process_events(&mut self) -> bool {
        self.poll.poll(&mut self.events, self.poll_duration).expect("poll failed");

        for event in self.events.iter() {
            match event.token() {
                MESSAGE => {
                    let mut done = false;

                    'process_batch: loop {
                        check_ctrlc!(self.keep_running);

                        let resp_start = self.response_counter.load(Ordering::SeqCst);

                        for i in 0..self.config.batch_size() {
                            match self.socket.recv_from(&mut self.buf) {
                                Ok((num_bytes, src_addr)) => {
                                    info!("Read bytes: {}", num_bytes);
                                    match self.nonce_from_request(&self.buf, num_bytes) {
                                        Ok(nonce) => {
                                            self.requests.push((Vec::from(nonce), src_addr));
                                            self.merkle.push_leaf(nonce);
                                        },
                                        Err(e) => {
                                           self.num_bad_requests += 1;

                                             info!(
                                                "Invalid request: '{:?}' ({} bytes) from {} (#{} in batch, resp #{})",
                                                e, num_bytes, src_addr, i, resp_start + i as usize
                                            );
                                        }
                                    }
                                },
                                Err(e) => match e.kind() {
                                    ErrorKind::WouldBlock => {
                                        done = true;
                                        break;
                                    }
                                    _ => {
                                        error!(
                                            "Error receiving from socket: {:?}: {:?}",
                                            e.kind(),
                                            e
                                        );
                                        break;
                                    }
                                },
                            };
                        }

                        if self.requests.is_empty() {
                            break 'process_batch;
                        }

                        let merkle_root = self.merkle.compute_root();
                        let srep = self.online_key.make_srep(time::get_time(), &merkle_root);

                        for (i, &(ref nonce, ref src_addr)) in self.requests.iter().enumerate() {
                            let paths = self.merkle.get_paths(i);

                            let resp = make_response(&srep, &self.cert_bytes, &paths, i as u32);
                            let resp_bytes = resp.encode().unwrap();

                            let bytes_sent = self.socket
                                .send_to(&resp_bytes, &src_addr)
                                .expect("send_to failed");
                            let num_responses = self.response_counter.fetch_add(1, Ordering::SeqCst);

                            info!(
                                "Responded {} bytes to {} for '{}..' (#{} in batch, resp #{})",
                                bytes_sent,
                                src_addr,
                                hex::encode(&nonce[0..4]),
                                i,
                                num_responses
                            );
                        }

                        self.merkle.reset();
                        self.requests.clear();

                        if done {
                            break 'process_batch;
                        }
                    }
                }

                STATUS => {
                    info!(
                        "responses {}, invalid requests {}",
                        self.response_counter.load(Ordering::SeqCst),
                        self.num_bad_requests
                    );

                    self.timer.set_timeout(self.config.status_interval(), ());
                }

                _ => unreachable!(),
            }
        }
        false
    }

    #[cfg(fuzzing)]
    pub fn send_to_self(&mut self, data: &[u8]) {
        self.response_counter.store(0,  Ordering::SeqCst);;
        self.num_bad_requests = 0;
        let res = self.fake_client_socket.send_to(data, &self.socket.local_addr().unwrap());
        info!("Sent to self: {:?}", res);
    }

    pub fn get_public_key(&self) -> &str {
        return &self.public_key
    }

    pub fn get_online_key(&self) -> &OnlineKey {
        return &self.online_key
    }

    pub fn get_config(&self) -> &Box<ServerConfig> {
        return &self.config
    }
}
<commit_msg>Add some documentation, remove more debugging statements<commit_after>use std::env;
use std::io::ErrorKind;
use std::process;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
use std::net::SocketAddr;
use hex;
use time;

use byteorder::{LittleEndian, WriteBytesExt};

use mio::net::UdpSocket;
use mio::{Events, Poll, PollOpt, Ready, Token};
use mio_extras::timer::Timer;

use config;
use config::ServerConfig;
use kms;
use key::{LongTermKey, OnlineKey};
use merkle::MerkleTree;
use {Error, RtMessage, Tag};
use {MIN_REQUEST_LENGTH, VERSION};

macro_rules! check_ctrlc {
    ($keep_running:expr) => {
        if !$keep_running.load(Ordering::Acquire) {
            warn!("Ctrl-C caught, exiting...");
            return true;
        }
    }
}

const MESSAGE: Token = Token(0);
const STATUS: Token = Token(1);

/// The main server instance.
/// A Server is initialiezd from a Server Config
/// and processes incoming messages in
/// 'process_events'
pub struct Server {
    config: Box<ServerConfig>,
    online_key: OnlineKey,
    cert_bytes: Vec<u8>,

    response_counter: AtomicUsize,
    num_bad_requests: u64,

    socket: UdpSocket,
    fake_client_socket: UdpSocket,
    keep_running: Arc<AtomicBool>,
    poll_duration: Option<Duration>,
    timer: Timer<()>,
    poll: Poll,
    events: Events,
    merkle: MerkleTree,
    requests: Vec<(Vec<u8>, SocketAddr)>,
    buf: [u8; 65_536],

    public_key: String,
}

impl Server {
    pub fn new(config: Box<ServerConfig>) -> Server {

        let mut online_key = OnlineKey::new();
        let public_key: String;

        let cert_bytes = {
            let seed = kms::load_seed(&config).unwrap();
            let mut long_term_key = LongTermKey::new(&seed);
            public_key = hex::encode(long_term_key.public_key());

            long_term_key.make_cert(&online_key).encode().unwrap()
        };

        let response_counter = AtomicUsize::new(0);
        let keep_running = Arc::new(AtomicBool::new(true));

        let sock_addr = config.socket_addr().expect("");
        let socket = UdpSocket::bind(&sock_addr).expect("failed to bind to socket");
        let fake_client_socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap()).unwrap();

        let poll_duration = Some(Duration::from_millis(100));

        let mut timer: Timer<()> = Timer::default();
        timer.set_timeout(config.status_interval(), ());

        let poll = Poll::new().unwrap();
        poll.register(&socket, MESSAGE, Ready::readable(), PollOpt::edge())
            .unwrap();
        //poll.register(&timer, STATUS, Ready::readable(), PollOpt::edge())
        //    .unwrap();

        let mut merkle = MerkleTree::new();
        let mut requests = Vec::with_capacity(config.batch_size() as usize);

        Server {
            config,
            online_key,
            cert_bytes,

            response_counter,
            num_bad_requests: 0,
            socket,
            fake_client_socket,
            keep_running,
            poll_duration,
            timer,
            poll,
            events: Events::with_capacity(32),
            merkle,
            requests,
            buf: [0u8; 65_536],

            public_key
        }

    }

    pub fn get_keep_running(&self) -> Arc<AtomicBool> {
        return self.keep_running.clone()
    }

    // extract the client's nonce from its request
    fn nonce_from_request<'a>(&self, buf: &'a [u8], num_bytes: usize) -> Result<&'a [u8], Error> {
        if num_bytes < MIN_REQUEST_LENGTH as usize {
            return Err(Error::RequestTooShort);
        }

        let tag_count = &buf[..4];
        let expected_nonc = &buf[8..12];
        let expected_pad = &buf[12..16];

        let tag_count_is_2 = tag_count == [0x02, 0x00, 0x00, 0x00];
        let tag1_is_nonc = expected_nonc == Tag::NONC.wire_value();
        let tag2_is_pad = expected_pad == Tag::PAD.wire_value();

        if tag_count_is_2 && tag1_is_nonc && tag2_is_pad {
            Ok(&buf[0x10..0x50])
        } else {
            Err(Error::InvalidRequest)
        }
    }

    fn make_response(&self, srep: &RtMessage, cert_bytes: &[u8], path: &[u8], idx: u32) -> RtMessage {
        let mut index = [0; 4];
        (&mut index as &mut [u8])
            .write_u32::<LittleEndian>(idx)
            .unwrap();

        let sig_bytes = srep.get_field(Tag::SIG).unwrap();
        let srep_bytes = srep.get_field(Tag::SREP).unwrap();

        let mut response = RtMessage::new(5);
        response.add_field(Tag::SIG, sig_bytes).unwrap();
        response.add_field(Tag::PATH, path).unwrap();
        response.add_field(Tag::SREP, srep_bytes).unwrap();
        response.add_field(Tag::CERT, cert_bytes).unwrap();
        response.add_field(Tag::INDX, &index).unwrap();

        response
    }

    /// The main processing function for incoming connections.
    /// This method should be called repeatedly in a loop
    /// to process requests. It returns 'true' when the server
    /// has shutdown (due to keep_running being set to 'false')
    pub fn process_events(&mut self) -> bool {
        self.poll.poll(&mut self.events, self.poll_duration).expect("poll failed");

        for event in self.events.iter() {
            match event.token() {
                MESSAGE => {
                    let mut done = false;

                    'process_batch: loop {
                        check_ctrlc!(self.keep_running);

                        let resp_start = self.response_counter.load(Ordering::SeqCst);

                        for i in 0..self.config.batch_size() {
                            match self.socket.recv_from(&mut self.buf) {
                                Ok((num_bytes, src_addr)) => {
                                    match self.nonce_from_request(&self.buf, num_bytes) {
                                        Ok(nonce) => {
                                            self.requests.push((Vec::from(nonce), src_addr));
                                            self.merkle.push_leaf(nonce);
                                        },
                                        Err(e) => {
                                           self.num_bad_requests += 1;

                                             info!(
                                                "Invalid request: '{:?}' ({} bytes) from {} (#{} in batch, resp #{})",
                                                e, num_bytes, src_addr, i, resp_start + i as usize
                                            );
                                        }
                                    }
                                },
                                Err(e) => match e.kind() {
                                    ErrorKind::WouldBlock => {
                                        done = true;
                                        break;
                                    }
                                    _ => {
                                        error!(
                                            "Error receiving from socket: {:?}: {:?}",
                                            e.kind(),
                                            e
                                        );
                                        break;
                                    }
                                },
                            };
                        }

                        if self.requests.is_empty() {
                            break 'process_batch;
                        }

                        let merkle_root = self.merkle.compute_root();
                        let srep = self.online_key.make_srep(time::get_time(), &merkle_root);

                        for (i, &(ref nonce, ref src_addr)) in self.requests.iter().enumerate() {
                            let paths = self.merkle.get_paths(i);

                            let resp = self.make_response(&srep, &self.cert_bytes, &paths, i as u32);
                            let resp_bytes = resp.encode().unwrap();

                            let bytes_sent = self.socket
                                .send_to(&resp_bytes, &src_addr)
                                .expect("send_to failed");
                            let num_responses = self.response_counter.fetch_add(1, Ordering::SeqCst);

                            info!(
                                "Responded {} bytes to {} for '{}..' (#{} in batch, resp #{})",
                                bytes_sent,
                                src_addr,
                                hex::encode(&nonce[0..4]),
                                i,
                                num_responses
                            );
                        }

                        self.merkle.reset();
                        self.requests.clear();

                        if done {
                            break 'process_batch;
                        }
                    }
                }

                STATUS => {
                    info!(
                        "responses {}, invalid requests {}",
                        self.response_counter.load(Ordering::SeqCst),
                        self.num_bad_requests
                    );

                    self.timer.set_timeout(self.config.status_interval(), ());
                }

                _ => unreachable!(),
            }
        }
        false
    }

    #[cfg(fuzzing)]
    pub fn send_to_self(&mut self, data: &[u8]) {
        self.response_counter.store(0,  Ordering::SeqCst);;
        self.num_bad_requests = 0;
        let res = self.fake_client_socket.send_to(data, &self.socket.local_addr().unwrap());
        info!("Sent to self: {:?}", res);
    }

    pub fn get_public_key(&self) -> &str {
        return &self.public_key
    }

    pub fn get_online_key(&self) -> &OnlineKey {
        return &self.online_key
    }

    pub fn get_config(&self) -> &Box<ServerConfig> {
        return &self.config
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::ops::Deref;
use std::io;
use std::error::FromError;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    Word,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true);
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION);
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = ();
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = self.listener.accept().unwrap().unwrap(); // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered timer has expired
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let request = message.init_root::<rpc_request::Builder>();

        match token {
            ELECTION_TIMEOUT => {
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                let _send_message = self.replica.election_timeout(request.init_request_vote());
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
                // TODO: send messages if necessary
            },
            HEARTBEAT_TIMEOUT => {
                let _send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
                // TODO: send messages if necessary
            },
            _ => unreachable!(),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: Option<MallocMessageBuilder>,
}

impl Connection {
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(-1),
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: Some(MallocMessageBuilder::new_default()),
        }
    }

    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                // TODO: We're *probably* not ready to shoot data again?
                match (self.current_write.has_remaining(), self.next_write.is_some()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, true) => try!(
                        serialize_packed::write_packed_message_unbuffered(&mut self.current_write,
                                                                          self.next_write.as_mut().unwrap())
                    ),
                    // We're done writing for now.
                    (false, false) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => panic!("Couldn't write!"),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        let from = self.stream.peer_addr().unwrap();
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => panic!("Error on reading."),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(from, reader, event_loop, replica);
                },
                // It's not read entirely yet.
                Err(_) => (),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn handle_reader<S, M>(&mut self, from: SocketAddr, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            // We will be responding.
            let response = match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    replica.append_entries_request(from, call, builder)
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let builder = builder_message.init_root::<request_vote_response::Builder>();
                    replica.request_vote_request(from, call, builder)
                },
                _ => unimplemented!(),
            };
            match response {
                Some(Emit) => {
                    // TODO
                    unimplemented!();
                    self.interest.insert(Interest::writable());
                },
                None            => (),
            }
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let res = builder_message.init_root::<append_entries_request::Builder>();
                    match replica.append_entries_response(from, call, res) {
                        Some(Emit) => {
                            // TODO
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let res = builder_message.init_root::<append_entries_request::Builder>();
                    match replica.request_vote_response(from, call, res) {
                        Some(Broadcast) => {
                            // Won an election!
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    match replica.client_append(from, call, res) {
                        Some(emit) => {
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    res.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    match replica.client_leader_refresh(from, res) {
                        Some(emit) => {
                            unimplemented!();
                            self.interest.insert(Interest::writable())
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }
}
<commit_msg>Note for future<commit_after>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::ops::Deref;
use std::io;
use std::error::FromError;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    Word,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true);
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION);
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = ();
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = self.listener.accept().unwrap().unwrap(); // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered timer has expired
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let request = message.init_root::<rpc_request::Builder>();

        match token {
            ELECTION_TIMEOUT => {
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                let _send_message = self.replica.election_timeout(request.init_request_vote());
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
                // TODO: send messages if necessary
            },
            HEARTBEAT_TIMEOUT => {
                let _send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
                // TODO: send messages if necessary
            },
            _ => unreachable!(),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: Option<MallocMessageBuilder>,
}

impl Connection {
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(-1),
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: Some(MallocMessageBuilder::new_default()),
        }
    }

    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                // TODO: We're *probably* not ready to shoot data again?
                match (self.current_write.has_remaining(), self.next_write.is_some()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, true) => try!(
                        serialize_packed::write_packed_message_unbuffered(&mut self.current_write,
                                                                          self.next_write.as_mut().unwrap())
                    ),
                    // We're done writing for now.
                    (false, false) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => panic!("Couldn't write!"),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        let from = self.stream.peer_addr().unwrap();
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => panic!("Error on reading."),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(from, reader, event_loop, replica);
                },
                // It's not read entirely yet.
                // Should roll back, pending changes to bytes upstream.
                Err(_) => unimplemented!(),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn handle_reader<S, M>(&mut self, from: SocketAddr, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            // We will be responding.
            let response = match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    replica.append_entries_request(from, call, builder)
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let builder = builder_message.init_root::<request_vote_response::Builder>();
                    replica.request_vote_request(from, call, builder)
                },
                _ => unimplemented!(),
            };
            match response {
                Some(Emit) => {
                    // TODO
                    unimplemented!();
                    self.interest.insert(Interest::writable());
                },
                None            => (),
            }
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let res = builder_message.init_root::<append_entries_request::Builder>();
                    match replica.append_entries_response(from, call, res) {
                        Some(Emit) => {
                            // TODO
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let res = builder_message.init_root::<append_entries_request::Builder>();
                    match replica.request_vote_response(from, call, res) {
                        Some(Broadcast) => {
                            // Won an election!
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    match replica.client_append(from, call, res) {
                        Some(emit) => {
                            unimplemented!();
                            self.interest.insert(Interest::writable());
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    res.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    match replica.client_leader_refresh(from, res) {
                        Some(emit) => {
                            unimplemented!();
                            self.interest.insert(Interest::writable())
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }
}
<|endoftext|>