@earl.lapus (Earl) posted a new topic, subject "Nix crate's fork() call". It read:

   Hi, I'm trying to learn more Rust by writing the examples in Beej's Guide to Network Programming from C to Rust. 
    
    I have this block code (TCP server accepting connections from a client):
    [code] 
            match listener.accept() {
                Ok((mut stream, addr)) => {
                    println!("connection accepted: {:?}", addr);
                    match fork() {
                        Ok(ForkResult8b7c:f320:99b9:690f:4595:cd17:293a:c069hild) => {
                            stream.write(b"Hello world!")?;
                            stream.flush()?;
                            stream.shutdown(Shutdown8b7c:f320:99b9:690f:4595:cd17:293a:c069oth).expect("Child shutdown failed")
                        },
                        Ok(ForkResult8b7c:f320:99b9:690f:4595:cd17:293a:c069Parent {child: _, ..}) => {
                            println!("Parent...");
                            stream.shutdown(Shutdown8b7c:f320:99b9:690f:4595:cd17:293a:c069oth).expect("Parent shutdown failed")
                        },
                        Err(_) => {
                            println!("fork() failed")
                        },
                    }
                },
                Err(e) => println!("attempt from client: {:?} failed", e),
            }
        
    [/code]
    
    I am using the nix crate to fork() a new process. I was expecting the _stream_ in both the parent block and the child block to be different copies. But, it looks like they are the same. Running the code above, I get the following error when a client connects:
    [code] 
        Parent...
        Error: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
        
    [/code]
    
    But if I comment out the _stream.shutdown()_ call in the parent block, then the client can connect and receive the message.
    
    Is this behavior inherent to the Rust language? -OR- is it an implementation specific behavior and I should be asking the folks from nix for clarifications about this?

To which @bjorn3 (Bjorn3) replied

    doc.rust-lang.org
    
    ### TcpStream in st8b7c:f320:99b9:690f:4595:cd17:293a:c069net - Rust
    
    A TCP stream between a local and a remote socket.
    
    > Shuts down the read, write, or both halves of this connection.
    > 
    > This function will cause all pending and future I/O on the specified portions to return immediately with an appropriate value (see the documentation of  `Shutdown` ).
    
    By forking a process you can't magically duplicate a TCP connection. A TCP connection is uniquely determined by source/destination ip and port. `stream.shutdown()` sends an `RST` packet to the system you are connected with closing the connection on both ends.

To which @earl.lapus (Earl) replied

    I see. So is it correct to say that in this context, both the parent and the child processes are sharing the same resource (TCP connection)?

After which, @bjorn3 (Bjorn3) added

    Yes

So @Hyeonu (A goat who barf on unsafe) replied

    To be honest fork-per-connection is a strategy which was common before we invented the thread. Linux and other OSes invented the thread because the process-per-connection model is too slow for internet scale servers, and just before the millennium we invented the async programming because the thread-per-connection model is too slow for web scale servers, AKA C10K problem.
    
    I'd recommend not to use fork() for concurrency/parallelism, especially for Rust. It would not works well with modern multithreading tools, which is really common in the Rust ecosystem.

Then @system (system) said

    This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.


{'source': 'discourse', 'url': 'https://users.rust-lang.org/t/nix-crates-fork-call/49033', 'title': "Nix crate's fork() call", 'views': 430, 'has_accepted_answer': False, 'word_count': 469, 'like_count': 5, 'reply_count': 1, 'participant_count': 3, 'posts': 6, 'tags': '', 'author': '@earl.lapus (Earl)', 'participants': '@earl.lapus (Earl), @bjorn3 (Bjorn3), @Hyeonu (A goat who barf on unsafe), @system (system)', 'image_url': [None], 'created_at': '2020-09-20T09:29:46.663Z', 'last_posted_at': '2020-12-19T10:22:13.132Z'}