Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gracefully shutdown server? #245

Open
dy93 opened this issue Jan 25, 2016 · 2 comments
Open

gracefully shutdown server? #245

dy93 opened this issue Jan 25, 2016 · 2 comments

Comments

@dy93
Copy link

dy93 commented Jan 25, 2016

thanks for your help to add public api for getting connection object in issue 238

but my problem still not solved. the file download process started before GOAWAY frame should success in the end.
here's the sample code to explain my problem:

var spdy = require('spdy'),
    fs = require('fs');

var options = {
    key: fs.readFileSync(__dirname + '/my.key'),
    cert: fs.readFileSync(__dirname + '/my.crt'),

    // **optional** SPDY-specific options
    spdy: {
        protocols: ['h2'],
        plain: false,

        connection: {
            windowSize: 1024 * 1024, // Server's window size
            // **optional** if true - server will send 3.1 frames on 3.0 *plain* spdy
            autoSpdy31: false
        }
    }
};

var server = spdy.createServer(options, function (req, res) {
    if (req.url !== '/file') {
        // simple web page to show download link
        res.writeHead(200);
        res.end("<html><head><title>test</title></head><body><a href='file'>get file</a></body></html>");
        return;
    }

    var stats = fs.statSync('./large.bin');
    var rs = fs.createReadStream('./large.bin');
    res.writeHead(200, {
        'Content-Type': 'application/octet-stream',
        'Content-Disposition': 'attachment; filename="file"',
        'Content-Length': stats.size
    });
    rs.pipe(res, { end: true });

    setTimeout(function () {
        console.log('send GOAWAY');
        res.spdyStream.connection.end();
    }, 2000);   // simulate shutdown server after 2 seconds. And the file download process *should* successfully complete
});

server.listen(4000);

to run this sample, you should generate a large file named large.bin (the size is depends on your network speed, it should be large enough that can not be complete downloaded in 2 seconds)

  1. start the server
  2. open the browser and navigate to the server: https://ip:4000
  3. click the get file link, and the download process start
  4. after 2 seconds, server will send GOAWAY frame
  5. since download process was started before GOAWAY frame, it should success in the end.

but i just get "network error" in my chrome, and download process failed
I think it may be a problem that server lake of "END_STREAM" flag in the last DATA frame ?

here is my environment:
node-spdy: 3.2.0
chrome: 47.0.2526.111 m

@dy93
Copy link
Author

dy93 commented Mar 30, 2016

Hey! Here is update:
I found that the problem was remove stream too early, this is a simpler code to reproduce the situation:

var spdy = require('spdy'),
    fs = require('fs');
var options = {
    key: fs.readFileSync(__dirname + '/my.key'),
    cert: fs.readFileSync(__dirname + '/my.crt'),
    spdy: {
        protocols: ['h2'],
        plain: false,
        connection: {
            windowSize: 1024 * 1024,
            autoSpdy31: false
        }
    }
};


var server = spdy.createServer(options, function(req, res) {
    res.spdyStream.connection.end(); // send GOAWAY frame

    setTimeout(function(){
        res.writeHead('200');
        res.end('hello'); // client should get this "hello"
    }, 1000);
});

server.listen(443);

when I visit the server from the browser, I just get connection closed unexpectedly.

If I comment out self.on('_streamDrain', self._onStreamDrain); in Connection.prototype._goaway in spdy-transport/lib/spdy-transport/connection.js, I can get the "hello" perfectly

The problem was that we remove stream too early (with adding DEBUG=* when executing server, I found that spdy remove the stream just after sending DATA frame which contains "hello" but before the DATA frame which contains "END_STREAM" flag)

Since DATA frame which containing "END_STREAM" cannot be delivered to browser before tcp connection closed, browser abort any DATA frame received previously.

Please solve this problem, thank you!

@daviddias
Copy link
Member

@dy93 could you check if this is still a issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants