mirror of https://github.com/fafhrd91/actix-net
				
				
				
			clean up actix-server code
This commit is contained in:
		
							parent
							
								
									05d8551066
								
							
						
					
					
						commit
						0df09dc81d
					
				| 
						 | 
					@ -2,7 +2,7 @@ use std::pin::Pin;
 | 
				
			||||||
use std::task::{Context, Poll};
 | 
					use std::task::{Context, Poll};
 | 
				
			||||||
use std::{fmt, io};
 | 
					use std::{fmt, io};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use bytes::{Buf, BytesMut};
 | 
					use bytes::{Buf, BufMut, BytesMut};
 | 
				
			||||||
use futures_core::{ready, Stream};
 | 
					use futures_core::{ready, Stream};
 | 
				
			||||||
use futures_sink::Sink;
 | 
					use futures_sink::Sink;
 | 
				
			||||||
use pin_project::pin_project;
 | 
					use pin_project::pin_project;
 | 
				
			||||||
| 
						 | 
					@ -222,15 +222,19 @@ impl<T, U> Framed<T, U> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // FixMe: Is this the right way to do it for now?
 | 
					            // FixMe: Is this the right way to do it for now?
 | 
				
			||||||
            let mut buf = ReadBuf::new(&mut this.read_buf);
 | 
					            let mut read = ReadBuf::uninit(this.read_buf.bytes_mut());
 | 
				
			||||||
            let cnt = match this.io.poll_read(cx, &mut buf) {
 | 
					            let cnt = match this.io.poll_read(cx, &mut read) {
 | 
				
			||||||
                Poll::Pending => return Poll::Pending,
 | 
					                Poll::Pending => return Poll::Pending,
 | 
				
			||||||
                Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e.into()))),
 | 
					                Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e.into()))),
 | 
				
			||||||
                Poll::Ready(Ok(())) => buf.filled().len(),
 | 
					                Poll::Ready(Ok(())) => read.filled().len(),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if cnt == 0 {
 | 
					            if cnt == 0 {
 | 
				
			||||||
                this.flags.insert(Flags::EOF);
 | 
					                this.flags.insert(Flags::EOF);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                unsafe {
 | 
				
			||||||
 | 
					                    this.read_buf.advance_mut(cnt);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            this.flags.insert(Flags::READABLE);
 | 
					            this.flags.insert(Flags::READABLE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,49 +44,49 @@ async fn test_rustls_string() {
 | 
				
			||||||
    assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
					    assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[actix_rt::test]
 | 
					// #[actix_rt::test]
 | 
				
			||||||
async fn test_static_str() {
 | 
					// async fn test_static_str() {
 | 
				
			||||||
    let srv = TestServer::with(|| {
 | 
					//     let srv = TestServer::with(|| {
 | 
				
			||||||
        fn_service(|io: TcpStream| async {
 | 
					//         fn_service(|io: TcpStream| async {
 | 
				
			||||||
            let mut framed = Framed::new(io, BytesCodec);
 | 
					//             let mut framed = Framed::new(io, BytesCodec);
 | 
				
			||||||
            framed.send(Bytes::from_static(b"test")).await?;
 | 
					//             framed.send(Bytes::from_static(b"test")).await?;
 | 
				
			||||||
            Ok::<_, io::Error>(())
 | 
					//             Ok::<_, io::Error>(())
 | 
				
			||||||
        })
 | 
					//         })
 | 
				
			||||||
    });
 | 
					//     });
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     let resolver = actix_connect::start_default_resolver().await.unwrap();
 | 
				
			||||||
 | 
					//     let mut conn = actix_connect::new_connector(resolver.clone());
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
 | 
				
			||||||
 | 
					//     assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     let connect = Connect::new(srv.host().to_owned());
 | 
				
			||||||
 | 
					//     let mut conn = actix_connect::new_connector(resolver);
 | 
				
			||||||
 | 
					//     let con = conn.call(connect).await;
 | 
				
			||||||
 | 
					//     assert!(con.is_err());
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let resolver = actix_connect::start_default_resolver().await.unwrap();
 | 
					// #[actix_rt::test]
 | 
				
			||||||
    let mut conn = actix_connect::new_connector(resolver.clone());
 | 
					// async fn test_new_service() {
 | 
				
			||||||
 | 
					//     let srv = TestServer::with(|| {
 | 
				
			||||||
    let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
 | 
					//         fn_service(|io: TcpStream| async {
 | 
				
			||||||
    assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
					//             let mut framed = Framed::new(io, BytesCodec);
 | 
				
			||||||
 | 
					//             framed.send(Bytes::from_static(b"test")).await?;
 | 
				
			||||||
    let connect = Connect::new(srv.host().to_owned());
 | 
					//             Ok::<_, io::Error>(())
 | 
				
			||||||
    let mut conn = actix_connect::new_connector(resolver);
 | 
					//         })
 | 
				
			||||||
    let con = conn.call(connect).await;
 | 
					//     });
 | 
				
			||||||
    assert!(con.is_err());
 | 
					//
 | 
				
			||||||
}
 | 
					//     let resolver =
 | 
				
			||||||
 | 
					//         actix_connect::start_resolver(ResolverConfig::default(), ResolverOpts::default())
 | 
				
			||||||
#[actix_rt::test]
 | 
					//             .await
 | 
				
			||||||
async fn test_new_service() {
 | 
					//             .unwrap();
 | 
				
			||||||
    let srv = TestServer::with(|| {
 | 
					//
 | 
				
			||||||
        fn_service(|io: TcpStream| async {
 | 
					//     let factory = actix_connect::new_connector_factory(resolver);
 | 
				
			||||||
            let mut framed = Framed::new(io, BytesCodec);
 | 
					//
 | 
				
			||||||
            framed.send(Bytes::from_static(b"test")).await?;
 | 
					//     let mut conn = factory.new_service(()).await.unwrap();
 | 
				
			||||||
            Ok::<_, io::Error>(())
 | 
					//     let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
 | 
				
			||||||
        })
 | 
					//     assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
				
			||||||
    });
 | 
					// }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    let resolver =
 | 
					 | 
				
			||||||
        actix_connect::start_resolver(ResolverConfig::default(), ResolverOpts::default())
 | 
					 | 
				
			||||||
            .await
 | 
					 | 
				
			||||||
            .unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let factory = actix_connect::new_connector_factory(resolver);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut conn = factory.new_service(()).await.unwrap();
 | 
					 | 
				
			||||||
    let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(con.peer_addr().unwrap(), srv.addr());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(all(feature = "openssl", feature = "uri"))]
 | 
					#[cfg(all(feature = "openssl", feature = "uri"))]
 | 
				
			||||||
#[actix_rt::test]
 | 
					#[actix_rt::test]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,9 +121,9 @@ fn non_static_block_on() {
 | 
				
			||||||
    let sys = actix_rt::System::new("borrow some");
 | 
					    let sys = actix_rt::System::new("borrow some");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sys.block_on(async {
 | 
					    sys.block_on(async {
 | 
				
			||||||
            actix_rt::time::sleep(Duration::from_millis(1)).await;
 | 
					        actix_rt::time::sleep(Duration::from_millis(1)).await;
 | 
				
			||||||
            assert_eq!("test_str", str);
 | 
					        assert_eq!("test_str", str);
 | 
				
			||||||
        });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rt = actix_rt::Runtime::new().unwrap();
 | 
					    let rt = actix_rt::Runtime::new().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,5 +135,6 @@ fn non_static_block_on() {
 | 
				
			||||||
    actix_rt::System::run(|| {
 | 
					    actix_rt::System::run(|| {
 | 
				
			||||||
        assert_eq!("test_str", str);
 | 
					        assert_eq!("test_str", str);
 | 
				
			||||||
        actix_rt::System::current().stop();
 | 
					        actix_rt::System::current().stop();
 | 
				
			||||||
    } ).unwrap();
 | 
					    })
 | 
				
			||||||
 | 
					    .unwrap();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -172,76 +172,40 @@ impl Accept {
 | 
				
			||||||
                let token = event.token();
 | 
					                let token = event.token();
 | 
				
			||||||
                match token {
 | 
					                match token {
 | 
				
			||||||
                    // This is a loop because interests for command were a loop that would try to
 | 
					                    // This is a loop because interests for command were a loop that would try to
 | 
				
			||||||
                    // drain the command channel. We break at first iter with other kind interests.
 | 
					                    // drain the command channel.
 | 
				
			||||||
                    WAKER_TOKEN => 'waker: loop {
 | 
					                    WAKER_TOKEN => 'waker: loop {
 | 
				
			||||||
                        match self.waker.pop() {
 | 
					                        match self.waker.pop() {
 | 
				
			||||||
                            Ok(i) => {
 | 
					                            Ok(WakerInterest::Notify) => {
 | 
				
			||||||
                                match i {
 | 
					                                self.maybe_backpressure(&mut sockets, false)
 | 
				
			||||||
                                    WakerInterest::Pause => {
 | 
					                            }
 | 
				
			||||||
                                        for (_, info) in sockets.iter_mut() {
 | 
					                            Ok(WakerInterest::Pause) => {
 | 
				
			||||||
                                            if let Err(err) =
 | 
					                                for (_, info) in sockets.iter_mut() {
 | 
				
			||||||
                                                self.poll.registry().deregister(&mut info.sock)
 | 
					                                    if let Err(err) =
 | 
				
			||||||
                                            {
 | 
					                                        self.poll.registry().deregister(&mut info.sock)
 | 
				
			||||||
                                                error!(
 | 
					                                    {
 | 
				
			||||||
                                                    "Can not deregister server socket {}",
 | 
					                                        error!("Can not deregister server socket {}", err);
 | 
				
			||||||
                                                    err
 | 
					                                    } else {
 | 
				
			||||||
                                                );
 | 
					                                        info!("Paused accepting connections on {}", info.addr);
 | 
				
			||||||
                                            } else {
 | 
					 | 
				
			||||||
                                                info!(
 | 
					 | 
				
			||||||
                                                    "Paused accepting connections on {}",
 | 
					 | 
				
			||||||
                                                    info.addr
 | 
					 | 
				
			||||||
                                                );
 | 
					 | 
				
			||||||
                                            }
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    WakerInterest::Resume => {
 | 
					 | 
				
			||||||
                                        for (token, info) in sockets.iter_mut() {
 | 
					 | 
				
			||||||
                                            if let Err(err) = self.register(token, info) {
 | 
					 | 
				
			||||||
                                                error!(
 | 
					 | 
				
			||||||
                                                    "Can not resume socket accept process: {}",
 | 
					 | 
				
			||||||
                                                    err
 | 
					 | 
				
			||||||
                                                );
 | 
					 | 
				
			||||||
                                            } else {
 | 
					 | 
				
			||||||
                                                info!(
 | 
					 | 
				
			||||||
                                                    "Accepting connections on {} has been resumed",
 | 
					 | 
				
			||||||
                                                    info.addr
 | 
					 | 
				
			||||||
                                                );
 | 
					 | 
				
			||||||
                                            }
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    WakerInterest::Stop => {
 | 
					 | 
				
			||||||
                                        for (_, info) in sockets.iter_mut() {
 | 
					 | 
				
			||||||
                                            let _ =
 | 
					 | 
				
			||||||
                                                self.poll.registry().deregister(&mut info.sock);
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        return;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    WakerInterest::Worker(worker) => {
 | 
					 | 
				
			||||||
                                        self.backpressure(&mut sockets, false);
 | 
					 | 
				
			||||||
                                        self.workers.push(worker);
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    // timer and notify interests need to break the loop at first iter.
 | 
					 | 
				
			||||||
                                    WakerInterest::Timer => {
 | 
					 | 
				
			||||||
                                        self.process_timer(&mut sockets);
 | 
					 | 
				
			||||||
                                        break 'waker;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    WakerInterest::Notify => {
 | 
					 | 
				
			||||||
                                        self.backpressure(&mut sockets, false);
 | 
					 | 
				
			||||||
                                        break 'waker;
 | 
					 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            Err(err) => match err {
 | 
					                            Ok(WakerInterest::Resume) => {
 | 
				
			||||||
                                // the waker queue is empty so we break the loop
 | 
					                                for (token, info) in sockets.iter_mut() {
 | 
				
			||||||
                                WakerQueueError::Empty => break 'waker,
 | 
					                                    self.register_logged(token, info);
 | 
				
			||||||
                                // the waker queue is closed so we return
 | 
					 | 
				
			||||||
                                WakerQueueError::Closed => {
 | 
					 | 
				
			||||||
                                    for (_, info) in sockets.iter_mut() {
 | 
					 | 
				
			||||||
                                        let _ = self.poll.registry().deregister(&mut info.sock);
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    return;
 | 
					 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            },
 | 
					                            }
 | 
				
			||||||
 | 
					                            Ok(WakerInterest::Stop) => {
 | 
				
			||||||
 | 
					                                return self.deregister_all(&mut sockets)
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            Ok(WakerInterest::Worker(worker)) => {
 | 
				
			||||||
 | 
					                                self.maybe_backpressure(&mut sockets, false);
 | 
				
			||||||
 | 
					                                self.workers.push(worker);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            Ok(WakerInterest::Timer) => self.process_timer(&mut sockets),
 | 
				
			||||||
 | 
					                            Err(WakerQueueError::Empty) => break 'waker,
 | 
				
			||||||
 | 
					                            Err(WakerQueueError::Closed) => {
 | 
				
			||||||
 | 
					                                return self.deregister_all(&mut sockets);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    _ => {
 | 
					                    _ => {
 | 
				
			||||||
| 
						 | 
					@ -261,15 +225,7 @@ impl Accept {
 | 
				
			||||||
        for (token, info) in sockets.iter_mut() {
 | 
					        for (token, info) in sockets.iter_mut() {
 | 
				
			||||||
            if let Some(inst) = info.timeout.take() {
 | 
					            if let Some(inst) = info.timeout.take() {
 | 
				
			||||||
                if now > inst {
 | 
					                if now > inst {
 | 
				
			||||||
                    if let Err(err) = self.poll.registry().register(
 | 
					                    self.register_logged(token, info);
 | 
				
			||||||
                        &mut info.sock,
 | 
					 | 
				
			||||||
                        MioToken(token + DELTA),
 | 
					 | 
				
			||||||
                        Interest::READABLE,
 | 
					 | 
				
			||||||
                    ) {
 | 
					 | 
				
			||||||
                        error!("Can not register server socket {}", err);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        info!("Resume accepting connections on {}", info.addr);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    info.timeout = Some(inst);
 | 
					                    info.timeout = Some(inst);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -307,23 +263,30 @@ impl Accept {
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
 | 
					    fn register_logged(&self, token: usize, info: &mut ServerSocketInfo) {
 | 
				
			||||||
 | 
					        match self.register(token, info) {
 | 
				
			||||||
 | 
					            Ok(_) => info!("Resume accepting connections on {}", info.addr),
 | 
				
			||||||
 | 
					            Err(e) => error!("Can not register server socket {}", e),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn deregister_all(&mut self, sockets: &mut Slab<ServerSocketInfo>) {
 | 
				
			||||||
 | 
					        sockets.iter_mut().for_each(|(_, info)| {
 | 
				
			||||||
 | 
					            let _ = self.poll.registry().deregister(&mut info.sock);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
 | 
				
			||||||
        if self.backpressure {
 | 
					        if self.backpressure {
 | 
				
			||||||
            if !on {
 | 
					            if !on {
 | 
				
			||||||
                self.backpressure = false;
 | 
					                self.backpressure = false;
 | 
				
			||||||
                for (token, info) in sockets.iter_mut() {
 | 
					                for (token, info) in sockets.iter_mut() {
 | 
				
			||||||
                    if let Err(err) = self.register(token, info) {
 | 
					                    self.register_logged(token, info);
 | 
				
			||||||
                        error!("Can not resume socket accept process: {}", err);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        info!("Accepting connections on {} has been resumed", info.addr);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if on {
 | 
					        } else if on {
 | 
				
			||||||
            self.backpressure = true;
 | 
					            self.backpressure = true;
 | 
				
			||||||
            for (_, info) in sockets.iter_mut() {
 | 
					            self.deregister_all(sockets);
 | 
				
			||||||
                let _ = self.poll.registry().deregister(&mut info.sock);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -331,7 +294,10 @@ impl Accept {
 | 
				
			||||||
        if self.backpressure {
 | 
					        if self.backpressure {
 | 
				
			||||||
            while !self.workers.is_empty() {
 | 
					            while !self.workers.is_empty() {
 | 
				
			||||||
                match self.workers[self.next].send(msg) {
 | 
					                match self.workers[self.next].send(msg) {
 | 
				
			||||||
                    Ok(_) => (),
 | 
					                    Ok(_) => {
 | 
				
			||||||
 | 
					                        self.set_next();
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    Err(tmp) => {
 | 
					                    Err(tmp) => {
 | 
				
			||||||
                        self.srv.worker_faulted(self.workers[self.next].idx);
 | 
					                        self.srv.worker_faulted(self.workers[self.next].idx);
 | 
				
			||||||
                        msg = tmp;
 | 
					                        msg = tmp;
 | 
				
			||||||
| 
						 | 
					@ -345,8 +311,6 @@ impl Accept {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                self.next = (self.next + 1) % self.workers.len();
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let mut idx = 0;
 | 
					            let mut idx = 0;
 | 
				
			||||||
| 
						 | 
					@ -355,7 +319,7 @@ impl Accept {
 | 
				
			||||||
                if self.workers[self.next].available() {
 | 
					                if self.workers[self.next].available() {
 | 
				
			||||||
                    match self.workers[self.next].send(msg) {
 | 
					                    match self.workers[self.next].send(msg) {
 | 
				
			||||||
                        Ok(_) => {
 | 
					                        Ok(_) => {
 | 
				
			||||||
                            self.next = (self.next + 1) % self.workers.len();
 | 
					                            self.set_next();
 | 
				
			||||||
                            return;
 | 
					                            return;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        Err(tmp) => {
 | 
					                        Err(tmp) => {
 | 
				
			||||||
| 
						 | 
					@ -364,7 +328,7 @@ impl Accept {
 | 
				
			||||||
                            self.workers.swap_remove(self.next);
 | 
					                            self.workers.swap_remove(self.next);
 | 
				
			||||||
                            if self.workers.is_empty() {
 | 
					                            if self.workers.is_empty() {
 | 
				
			||||||
                                error!("No workers");
 | 
					                                error!("No workers");
 | 
				
			||||||
                                self.backpressure(sockets, true);
 | 
					                                self.maybe_backpressure(sockets, true);
 | 
				
			||||||
                                return;
 | 
					                                return;
 | 
				
			||||||
                            } else if self.workers.len() <= self.next {
 | 
					                            } else if self.workers.len() <= self.next {
 | 
				
			||||||
                                self.next = 0;
 | 
					                                self.next = 0;
 | 
				
			||||||
| 
						 | 
					@ -373,14 +337,19 @@ impl Accept {
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                self.next = (self.next + 1) % self.workers.len();
 | 
					                self.set_next();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // enable backpressure
 | 
					            // enable backpressure
 | 
				
			||||||
            self.backpressure(sockets, true);
 | 
					            self.maybe_backpressure(sockets, true);
 | 
				
			||||||
            self.accept_one(sockets, msg);
 | 
					            self.accept_one(sockets, msg);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // set next worker that would accept work.
 | 
				
			||||||
 | 
					    fn set_next(&mut self) {
 | 
				
			||||||
 | 
					        self.next = (self.next + 1) % self.workers.len();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn accept(&mut self, sockets: &mut Slab<ServerSocketInfo>, token: usize) {
 | 
					    fn accept(&mut self, sockets: &mut Slab<ServerSocketInfo>, token: usize) {
 | 
				
			||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            let msg = if let Some(info) = sockets.get_mut(token) {
 | 
					            let msg = if let Some(info) = sockets.get_mut(token) {
 | 
				
			||||||
| 
						 | 
					@ -402,10 +371,10 @@ impl Accept {
 | 
				
			||||||
                        // sleep after error
 | 
					                        // sleep after error
 | 
				
			||||||
                        info.timeout = Some(Instant::now() + Duration::from_millis(500));
 | 
					                        info.timeout = Some(Instant::now() + Duration::from_millis(500));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        let w = self.waker.clone();
 | 
					                        let waker = self.waker.clone();
 | 
				
			||||||
                        System::current().arbiter().send(Box::pin(async move {
 | 
					                        System::current().arbiter().send(Box::pin(async move {
 | 
				
			||||||
                            sleep_until(Instant::now() + Duration::from_millis(510)).await;
 | 
					                            sleep_until(Instant::now() + Duration::from_millis(510)).await;
 | 
				
			||||||
                            w.wake(WakerInterest::Timer);
 | 
					                            waker.wake(WakerInterest::Timer);
 | 
				
			||||||
                        }));
 | 
					                        }));
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,5 @@
 | 
				
			||||||
//! General purpose TCP server.
 | 
					//! General purpose TCP server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#![deny(rust_2018_idioms)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod accept;
 | 
					mod accept;
 | 
				
			||||||
mod builder;
 | 
					mod builder;
 | 
				
			||||||
mod config;
 | 
					mod config;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,7 +229,7 @@ impl Worker {
 | 
				
			||||||
            self.services.iter_mut().for_each(|srv| {
 | 
					            self.services.iter_mut().for_each(|srv| {
 | 
				
			||||||
                if srv.status == WorkerServiceStatus::Available {
 | 
					                if srv.status == WorkerServiceStatus::Available {
 | 
				
			||||||
                    srv.status = WorkerServiceStatus::Stopped;
 | 
					                    srv.status = WorkerServiceStatus::Stopped;
 | 
				
			||||||
                    actix_rt::spawn(
 | 
					                    spawn(
 | 
				
			||||||
                        srv.service
 | 
					                        srv.service
 | 
				
			||||||
                            .call((None, ServerMessage::ForceShutdown))
 | 
					                            .call((None, ServerMessage::ForceShutdown))
 | 
				
			||||||
                            .map(|_| ()),
 | 
					                            .map(|_| ()),
 | 
				
			||||||
| 
						 | 
					@ -241,7 +241,7 @@ impl Worker {
 | 
				
			||||||
            self.services.iter_mut().for_each(move |srv| {
 | 
					            self.services.iter_mut().for_each(move |srv| {
 | 
				
			||||||
                if srv.status == WorkerServiceStatus::Available {
 | 
					                if srv.status == WorkerServiceStatus::Available {
 | 
				
			||||||
                    srv.status = WorkerServiceStatus::Stopping;
 | 
					                    srv.status = WorkerServiceStatus::Stopping;
 | 
				
			||||||
                    actix_rt::spawn(
 | 
					                    spawn(
 | 
				
			||||||
                        srv.service
 | 
					                        srv.service
 | 
				
			||||||
                            .call((None, ServerMessage::Shutdown(timeout)))
 | 
					                            .call((None, ServerMessage::Shutdown(timeout)))
 | 
				
			||||||
                            .map(|_| ()),
 | 
					                            .map(|_| ()),
 | 
				
			||||||
| 
						 | 
					@ -304,21 +304,15 @@ enum WorkerState {
 | 
				
			||||||
    Restarting(
 | 
					    Restarting(
 | 
				
			||||||
        usize,
 | 
					        usize,
 | 
				
			||||||
        Token,
 | 
					        Token,
 | 
				
			||||||
        #[allow(clippy::type_complexity)]
 | 
					        LocalBoxFuture<'static, Result<Vec<(Token, BoxedServerService)>, ()>>,
 | 
				
			||||||
        Pin<Box<dyn Future<Output = Result<Vec<(Token, BoxedServerService)>, ()>>>>,
 | 
					 | 
				
			||||||
    ),
 | 
					 | 
				
			||||||
    Shutdown(
 | 
					 | 
				
			||||||
        Pin<Box<Sleep>>,
 | 
					 | 
				
			||||||
        Pin<Box<Sleep>>,
 | 
					 | 
				
			||||||
        Option<oneshot::Sender<bool>>,
 | 
					 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
 | 
					    Shutdown(Sleep, Sleep, Option<oneshot::Sender<bool>>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Future for Worker {
 | 
					impl Future for Worker {
 | 
				
			||||||
    type Output = ();
 | 
					    type Output = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // FIXME: remove this attribute
 | 
					    // #[allow(clippy::never_loop)]
 | 
				
			||||||
    #[allow(clippy::never_loop)]
 | 
					 | 
				
			||||||
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
 | 
					    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
 | 
				
			||||||
        // `StopWorker` message handler
 | 
					        // `StopWorker` message handler
 | 
				
			||||||
        if let Poll::Ready(Some(StopCommand { graceful, result })) =
 | 
					        if let Poll::Ready(Some(StopCommand { graceful, result })) =
 | 
				
			||||||
| 
						 | 
					@ -336,8 +330,8 @@ impl Future for Worker {
 | 
				
			||||||
                if num != 0 {
 | 
					                if num != 0 {
 | 
				
			||||||
                    info!("Graceful worker shutdown, {} connections", num);
 | 
					                    info!("Graceful worker shutdown, {} connections", num);
 | 
				
			||||||
                    self.state = WorkerState::Shutdown(
 | 
					                    self.state = WorkerState::Shutdown(
 | 
				
			||||||
                        Box::pin(sleep_until(Instant::now() + time::Duration::from_secs(1))),
 | 
					                        sleep_until(Instant::now() + time::Duration::from_secs(1)),
 | 
				
			||||||
                        Box::pin(sleep_until(Instant::now() + self.shutdown_timeout)),
 | 
					                        sleep_until(Instant::now() + self.shutdown_timeout),
 | 
				
			||||||
                        Some(result),
 | 
					                        Some(result),
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
| 
						 | 
					@ -391,9 +385,10 @@ impl Future for Worker {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            WorkerState::Restarting(idx, token, ref mut fut) => {
 | 
					            WorkerState::Restarting(idx, token, ref mut fut) => {
 | 
				
			||||||
                match Pin::new(fut).poll(cx) {
 | 
					                match fut.as_mut().poll(cx) {
 | 
				
			||||||
                    Poll::Ready(Ok(item)) => {
 | 
					                    Poll::Ready(Ok(item)) => {
 | 
				
			||||||
                        for (token, service) in item {
 | 
					                        // only interest in the first item?
 | 
				
			||||||
 | 
					                        if let Some((token, service)) = item.into_iter().next() {
 | 
				
			||||||
                            trace!(
 | 
					                            trace!(
 | 
				
			||||||
                                "Service {:?} has been restarted",
 | 
					                                "Service {:?} has been restarted",
 | 
				
			||||||
                                self.factories[idx].name(token)
 | 
					                                self.factories[idx].name(token)
 | 
				
			||||||
| 
						 | 
					@ -402,6 +397,15 @@ impl Future for Worker {
 | 
				
			||||||
                            self.state = WorkerState::Unavailable(Vec::new());
 | 
					                            self.state = WorkerState::Unavailable(Vec::new());
 | 
				
			||||||
                            return self.poll(cx);
 | 
					                            return self.poll(cx);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        // for (token, service) in item {
 | 
				
			||||||
 | 
					                        //     trace!(
 | 
				
			||||||
 | 
					                        //         "Service {:?} has been restarted",
 | 
				
			||||||
 | 
					                        //         self.factories[idx].name(token)
 | 
				
			||||||
 | 
					                        //     );
 | 
				
			||||||
 | 
					                        //     self.services[token.0].created(service);
 | 
				
			||||||
 | 
					                        //     self.state = WorkerState::Unavailable(Vec::new());
 | 
				
			||||||
 | 
					                        //     return self.poll(cx);
 | 
				
			||||||
 | 
					                        // }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Poll::Ready(Err(_)) => {
 | 
					                    Poll::Ready(Err(_)) => {
 | 
				
			||||||
                        panic!(
 | 
					                        panic!(
 | 
				
			||||||
| 
						 | 
					@ -424,26 +428,19 @@ impl Future for Worker {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // check graceful timeout
 | 
					                // check graceful timeout
 | 
				
			||||||
                match t2.as_mut().poll(cx) {
 | 
					                if Pin::new(t2).poll(cx).is_ready() {
 | 
				
			||||||
                    Poll::Pending => (),
 | 
					                    let _ = tx.take().unwrap().send(false);
 | 
				
			||||||
                    Poll::Ready(_) => {
 | 
					                    self.shutdown(true);
 | 
				
			||||||
                        let _ = tx.take().unwrap().send(false);
 | 
					                    Arbiter::current().stop();
 | 
				
			||||||
                        self.shutdown(true);
 | 
					                    return Poll::Ready(());
 | 
				
			||||||
                        Arbiter::current().stop();
 | 
					 | 
				
			||||||
                        return Poll::Ready(());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // sleep for 1 second and then check again
 | 
					                // sleep for 1 second and then check again
 | 
				
			||||||
                match t1.as_mut().poll(cx) {
 | 
					                if Pin::new(&mut *t1).poll(cx).is_ready() {
 | 
				
			||||||
                    Poll::Pending => (),
 | 
					                    *t1 = sleep_until(Instant::now() + time::Duration::from_secs(1));
 | 
				
			||||||
                    Poll::Ready(_) => {
 | 
					                    let _ = Pin::new(t1).poll(cx);
 | 
				
			||||||
                        *t1 = Box::pin(sleep_until(
 | 
					 | 
				
			||||||
                            Instant::now() + time::Duration::from_secs(1),
 | 
					 | 
				
			||||||
                        ));
 | 
					 | 
				
			||||||
                        let _ = t1.as_mut().poll(cx);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Poll::Pending
 | 
					                Poll::Pending
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            WorkerState::Available => {
 | 
					            WorkerState::Available => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -283,7 +283,7 @@ pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
 | 
					    S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let mut rt = actix_rt::System::new("test");
 | 
					    let rt = actix_rt::System::new("test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // start benchmark loops
 | 
					    // start benchmark loops
 | 
				
			||||||
    c.bench_function(name, move |b| {
 | 
					    c.bench_function(name, move |b| {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,7 @@ pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
 | 
					    S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let mut rt = actix_rt::System::new("test");
 | 
					    let rt = actix_rt::System::new("test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // start benchmark loops
 | 
					    // start benchmark loops
 | 
				
			||||||
    c.bench_function(name, move |b| {
 | 
					    c.bench_function(name, move |b| {
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ where
 | 
				
			||||||
            // exclude request generation, it appears it takes significant time vs call (3us vs 1us)
 | 
					            // exclude request generation, it appears it takes significant time vs call (3us vs 1us)
 | 
				
			||||||
            let start = std::time::Instant::now();
 | 
					            let start = std::time::Instant::now();
 | 
				
			||||||
            // benchmark body
 | 
					            // benchmark body
 | 
				
			||||||
            rt.block_on(async move { join_all(srvs.iter_mut().map(|srv| srv.call(()))).await });
 | 
					            rt.block_on(async { join_all(srvs.iter_mut().map(|srv| srv.call(()))).await });
 | 
				
			||||||
            // check that at least first request succeeded
 | 
					            // check that at least first request succeeded
 | 
				
			||||||
            start.elapsed()
 | 
					            start.elapsed()
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue