Giter Club home page Giter Club logo

Comments (2)

taiki-e avatar taiki-e commented on June 2, 2024

Why not use async? (It should already have the proper mechanisms to handle such cases.)

if e.kind() == std::io::ErrorKind::WouldBlock {
                        dbg!("zzz");
                        backoff.snooze();

It does not seem desirable to do an unbounded spin loop if OS returns WouldBlock.

from crossbeam.

Ben-PH avatar Ben-PH commented on June 2, 2024

That's what we have been using, but we have realised that async in our code-base was a mistake, and we are migrating away from it.

What we ended up doing, for now, is this:

pub struct BootstrapTcpListener {
    poll: Poll,
    events: Events,
    server: TcpListener,
    // HACK : create variable to move ownership of mio_server to the thread
    // if mio_server is not moved, poll does not receive any event from listener
    _mio_server: MioTcpListener,
}

pub enum PollEvent {
    NewConnection((TcpStream, SocketAddr)),
    Stop,
}

impl BSEventPoller for BootstrapTcpListener {
    fn poll(&mut self) -> Result<PollEvent, BootstrapError> {
        self.poll.poll(&mut self.events, None).unwrap();

        // Confirm that we are not being signalled to shut down
        if self.events.iter().any(|ev| ev.token() == STOP_LISTENER) {
            return Ok(PollEvent::Stop);
        }

        // Ther could be more than one connection ready, but we want to re-check for the stop
        // signal after processing each connection.
        return Ok(PollEvent::NewConnection(
            self.server.accept().map_err(BootstrapError::from)?,
        ));
    }
}

impl BootstrapListenerStopHandle {
    /// Stop the bootstrap listener.
    pub fn stop(self) -> Result<(), BootstrapError> {
        self.0.wake().map_err(BootstrapError::from)
    }
}

...and in the main event loop of the server, instead of using std::net::TcpListener::accept(...)?, we use our poll and match on the return enum.

Previously we would have a dedicated listener thread, and two crossbeam channels, one for a connection, one for a stop-signal broadcast:

loop {
    let conn = select! {
        recv(stopper_rx) -> _ => return Ok(()),
        recv(conn_rx) -> conn => conn,
    };
    // ...validate connection before dispatching to a system-thread to handle
}

What the change meant is that we no longer have a need for a dedicated listener thread, or a buffer of connections.

I see that my "MVP" is probably a bad label, and probably a distraction.

from crossbeam.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.