restify / restify/clients

client doesn't retry socket hang-up errors before response

Open
#162 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
58
Forks
35
Avg merge
22h 4m
Merged PRs (30d)
10

Description

COPIED: https://github.com/restify/node-restify/issues/483

The restify client doesn't retry socket hang-up errors that happen before a response is received. Here's a test program:

var mod_bunyan = require('bunyan');
var mod_fs = require('fs');
var mod_restify = require('restify');

var log, server, client, sockpath;

log = new mod_bunyan({
    'name': 'test',
    'level': process.env['LOG_LEVEL'] || 'info'
});

/* Clean up our UDS from an unclean shutdown. */
sockpath = '/tmp/mysock';
try {
        log.info('removing ', sockpath);
        mod_fs.unlinkSync(sockpath);
        log.info('removed ', sockpath);
} catch (ex) {
        if (ex['code'] != 'ENOENT')
                throw (ex);
        log.info('not found ', sockpath);
}

/*
 * Create a restify server that receives requests at /hello, waits 5 seconds,
 * and then closes the socket abruptly (before having sent any response).
 */
server = mod_restify.createServer();
server.get('/hello', function (req, res, next) {
        log.info('server: got request');
        req.socket.setTimeout(5000);

        /*
         * Close the client and server sockets 30 seconds after we receive the
         * first request so that our program exits.  This is just to demonstrate
         * that restify isn't actually retrying the request at this point.
         */
        setTimeout(function () {
                server.close();
                client.close();
        }, 30000);
});

/*
 * Start the server.  When it's ready, run the test case.
 */
server.listen(sockpath, function () {
        var rqoptions;

        log.info('server: listening');

        /*
         * Now that the server's up, create a restify client for the socket path
         * and submit a GET request to /hello.  We set the retry policy to 4
         * retries, but the restify client won't retry at all.
         */
        client = mod_restify.createStringClient({
            'socketPath': sockpath,
            'log': log,
            'version': '*'
        });

        rqoptions = {
            'path': '/hello',
            'retry': {
                'retries': 4,
                'minTimeout': 1000,
                'maxtimeout': 8000
            }
        };

        log.info('client: making request');
        client.get(rqoptions, function (err, req) {
                if (err) {
                        /*
                         * This is where the restify client reports an error --
                         * without having retried the request due to a socket
                         * hang-up.
                         */
                        log.error(err, 'client: error BEFORE request');
                        return;
                }

                log.info('client: request started');
                req.on('result', function (err2, res) {
                        if (err2) {
                                log.error(err2, 'client: error before response');
                                return;
                        }

                        log.info('client: response started');
                });
        });
});

Here's the output:

$ node -v
v0.8.26

$ time node test.js | bunyan
[2013-11-19T18:29:33.100Z]  INFO: test/34525 on bbc0462f: removing  /tmp/mysock
[2013-11-19T18:29:33.101Z]  INFO: test/34525 on bbc0462f: not found  /tmp/mysock
[2013-11-19T18:29:33.183Z]  INFO: test/34525 on bbc0462f: server: listening
[2013-11-19T18:29:33.202Z]  INFO: test/34525 on bbc0462f: client: making request
[2013-11-19T18:29:33.206Z]  INFO: test/34525 on bbc0462f: server: got request
[2013-11-19T18:29:38.208Z] ERROR: test/34525 on bbc0462f: client: error BEFORE request
    Error: socket hang up
        at createHangUpError (http.js:1379:15)
        at Socket.socketOnEnd (http.js:1476:23)
        at Pipe.onread (net.js:422:26)

real    0m30.312s
user    0m0.348s
sys     0m0.091s

Tried on restify 2.3.5, 2.6, and #master (9b07786060c240fcb1592289886d21d1f04c99c1).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the client retry handling and reproduce the socket hang-up with the supplied JavaScript program and retry options. The work is done when errors occurring before a response cause the configured retries to run, rather than being reported immediately.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.