rework of prior
authoralfadur
Thu, 14 Jun 2018 16:44:27 -0400
changeset 13415 0eedc17055a0
parent 13414 28b314ad566d
child 13416 cdf69667593b
rework of prior
gameServer2/src/server/network.rs
--- a/gameServer2/src/server/network.rs	Thu Jun 14 12:31:15 2018 -0400
+++ b/gameServer2/src/server/network.rs	Thu Jun 14 16:44:27 2018 -0400
@@ -3,7 +3,8 @@
 use std::{
     io, io::{Error, ErrorKind, Write},
     net::{SocketAddr, IpAddr, Ipv4Addr},
-    collections::VecDeque
+    collections::HashSet,
+    mem::swap
 };
 
 use mio::{
@@ -22,7 +23,7 @@
 
 const MAX_BYTES_PER_READ: usize = 2048;
 
-#[derive(PartialEq, Copy, Clone)]
+#[derive(Hash, Eq, PartialEq, Copy, Clone)]
 pub enum NetworkClientState {
     Idle,
     NeedsWrite,
@@ -90,8 +91,7 @@
             match self.buf_out.write_to(&mut self.socket) {
                 Ok(bytes) if self.buf_out.is_empty() || bytes == 0 =>
                     break Ok(((), NetworkClientState::Idle)),
-                Ok(bytes) =>
-                    (),
+                Ok(_) => (),
                 Err(ref error) if error.kind() == ErrorKind::Interrupted
                     || error.kind() == ErrorKind::WouldBlock => {
                     break Ok(((), NetworkClientState::NeedsWrite));
@@ -120,17 +120,18 @@
 pub struct NetworkLayer {
     listener: TcpListener,
     server: HWServer,
-
     clients: Slab<NetworkClient>,
-    pending: VecDeque<(ClientId, NetworkClientState)>
+    pending: HashSet<(ClientId, NetworkClientState)>,
+    pending_cache: Vec<(ClientId, NetworkClientState)>
 }
 
 impl NetworkLayer {
     pub fn new(listener: TcpListener, clients_limit: usize, rooms_limit: usize) -> NetworkLayer {
         let server = HWServer::new(clients_limit, rooms_limit);
         let clients = Slab::with_capacity(clients_limit);
-        let pending = VecDeque::with_capacity(clients_limit);
-        NetworkLayer {listener, server, clients, pending}
+        let pending = HashSet::with_capacity(2 * clients_limit);
+        let pending_cache = Vec::with_capacity(2 * clients_limit);
+        NetworkLayer {listener, server, clients, pending, pending_cache}
     }
 
     pub fn register_server(&self, poll: &Poll) -> io::Result<()> {
@@ -170,7 +171,7 @@
                 Destination::ToSelf(id)  => {
                     if let Some(ref mut client) = self.clients.get_mut(id) {
                         client.send_msg(msg);
-                        self.pending.push_back((id, NetworkClientState::NeedsWrite));
+                        self.pending.insert((id, NetworkClientState::NeedsWrite));
                     }
                 }
                 Destination::ToOthers(id) => {
@@ -178,7 +179,7 @@
                     for (client_id, client) in self.clients.iter_mut() {
                         if client_id != id {
                             client.send_string(&msg_string);
-                            self.pending.push_back((client_id, NetworkClientState::NeedsWrite));
+                            self.pending.insert((client_id, NetworkClientState::NeedsWrite));
                         }
                     }
                 }
@@ -223,8 +224,9 @@
                     self.server.handle_msg(client_id, message);
                 }
                 match state {
-                    NetworkClientState::NeedsRead =>
-                        self.pending.push_back((client_id, state)),
+                    NetworkClientState::NeedsRead => {
+                        self.pending.insert((client_id, state));
+                    },
                     NetworkClientState::Closed =>
                         self.client_error(&poll, client_id)?,
                     _ => {}
@@ -258,10 +260,10 @@
             };
 
         match result {
-            Ok(((), state)) if state == NetworkClientState::NeedsWrite =>
-                self.pending.push_back((client_id, state)),
-            Ok(_) =>
-                {}
+            Ok(((), state)) if state == NetworkClientState::NeedsWrite => {
+                self.pending.insert((client_id, state));
+            },
+            Ok(_) => {}
             Err(e) => self.operation_failed(
                 poll, client_id, e,
                 "Error while writing to client socket")?
@@ -283,14 +285,20 @@
     }
 
     pub fn on_idle(&mut self, poll: &Poll) -> io::Result<()> {
-        while let Some((id, state)) = self.pending.pop_front() {
-            match state {
-                NetworkClientState::NeedsRead =>
-                    self.client_readable(poll, id)?,
-                NetworkClientState::NeedsWrite =>
-                    self.client_writable(poll, id)?,
-                _ => {}
+        if self.has_pending_operations() {
+            let mut cache = Vec::new();
+            swap(&mut cache, &mut self.pending_cache);
+            cache.extend(self.pending.drain());
+            for (id, state) in cache.drain(..) {
+                match state {
+                    NetworkClientState::NeedsRead =>
+                        self.client_readable(poll, id)?,
+                    NetworkClientState::NeedsWrite =>
+                        self.client_writable(poll, id)?,
+                    _ => {}
+                }
             }
+            swap(&mut cache, &mut self.pending_cache);
         }
         Ok(())
     }