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

add functions to change timeout #34

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,21 @@ the response behavior. This error has a `.timeout` property as well as
Clears the timeout on the request. The timeout is completely removed and
will not fire for this request in the future.

### req.resetTimeout(time)

Resets the timeout on the request. The timeout is reset to the `time` given.

### req.addTimeout(time)

Adds to the timeout on the request. The timeout is increased by the `time` given.

### req.getTimeout()

Get the current timeout remaining (in milliseconds).

### req.timedout

`true` if timeout fired; `false` otherwise.
`true` if timeout fired; `false` otherwise. This will remain `true` if the timeout was changed after timeout was fired.

## Examples

Expand Down
60 changes: 45 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,52 @@ function timeout (time, options) {
var respond = opts.respond === undefined || opts.respond === true

return function (req, res, next) {
var id = setTimeout(function () {
req.timedout = true
req.emit('timeout', delay)
}, delay)
var started = Date.now()
var id = createTimeout(req, delay)

if (respond) {
req.on('timeout', onTimeout(delay, next))
req.on('timeout', function () {
next(createError(503, 'Response timeout', {
code: 'ETIMEDOUT',
timeout: delay
}))
})
}

req.clearTimeout = function () {
delay = 0
clearTimeout(id)
}

req.resetTimeout = function (newDelay) {
UziTech marked this conversation as resolved.
Show resolved Hide resolved
newDelay = typeof newDelay === 'string'
? ms(newDelay)
: Number(newDelay || 5000)
started = Date.now()
delay = newDelay
clearTimeout(id)
id = createTimeout(req, delay)
}

req.addTimeout = function (moreDelay) {
moreDelay = typeof moreDelay === 'string'
? ms(moreDelay)
: Number(moreDelay || 5000)
var timeLeft = req.getTimeout()
var actualDelay = timeLeft + moreDelay
delay = delay + moreDelay
if (timeLeft === 0) {
started = Date.now() + actualDelay - delay
}
clearTimeout(id)
id = createTimeout(req, actualDelay)
}

req.getTimeout = function () {
var time = delay - (Date.now() - started)
return (time > 0 ? time : 0)
}

req.timedout = false

onFinished(res, function () {
Expand All @@ -72,18 +105,15 @@ function timeout (time, options) {
}

/**
* Create timeout listener function.
* Create timeout.
*
* @param {stream} req
* @param {number} delay
* @param {function} cb
* @private
*/

function onTimeout (delay, cb) {
return function () {
cb(createError(503, 'Response timeout', {
code: 'ETIMEDOUT',
timeout: delay
}))
}
function createTimeout (req, delay) {
return setTimeout(function () {
req.timedout = true
req.emit('timeout', delay)
}, delay)
}
176 changes: 176 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,182 @@ describe('timeout()', function () {
})
})

describe('req.resetTimeout()', function () {
it('should reset the timeout', function (done) {
var server = createServer(null,
function (req, res) { req.resetTimeout(1000) },
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 1000)
})

request(server)
.get('/')
.expect(503, /1000ms/, done)
})
it('should reset the timeout with a string', function (done) {
var server = createServer(null,
function (req, res) { req.resetTimeout('1s') },
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 1000)
})

request(server)
.get('/')
.expect(503, /1000ms/, done)
})
it('should reset the timeout with 5000 default', function (done) {
this.timeout(10000)
var server = createServer(null,
function (req, res) { req.resetTimeout() },
UziTech marked this conversation as resolved.
Show resolved Hide resolved
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 5000)
})

request(server)
.get('/')
.expect(503, /5000ms/, done)
})
it('should still timeout after the new timeout', function (done) {
var server = createServer(null,
function (req, res) { setTimeout(function () { req.resetTimeout(120) }, 50) },
function (req, res) {
assert.ok(req.timedout)
res.end('Hello')
})

request(server)
.get('/')
.expect(503, /120ms/, done)
})
})

describe('req.addTimeout()', function () {
it('should reset the timeout', function (done) {
var server = createServer(null,
function (req, res) { req.addTimeout(1000) },
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 1000)
})

request(server)
.get('/')
.expect(503, /1100ms/, done)
})
it('should reset the timeout with a string', function (done) {
var server = createServer(null,
function (req, res) { req.addTimeout('1s') },
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 1000)
})

request(server)
.get('/')
.expect(503, /1100ms/, done)
})
it('should reset the timeout with 5000 default', function (done) {
this.timeout(10000)
var server = createServer(null,
function (req, res) { req.addTimeout() },
function (req, res) {
assert.ok(!req.timedout)
setTimeout(function () {
assert.ok(req.timedout)
res.end('Hello')
}, 5000)
})

request(server)
.get('/')
.expect(503, /5100ms/, done)
})
it('should still timeout after the new timeout', function (done) {
var server = createServer(null,
function (req, res) { req.addTimeout(90) },
function (req, res) {
assert.ok(req.timedout)
res.end('Hello')
})

request(server)
.get('/')
.expect(503, /190ms/, done)
})
it('should reset timeLeft if cleared', function (done) {
var server = createServer(null,
function (req, res) {
req.clearTimeout()
setTimeout(function () {
assert.equal(req.getTimeout(), 0)
req.addTimeout(10)
assert.ok(req.getTimeout() > 0 && req.getTimeout() <= 10)
}, 50)
},
function (req, res) {
assert.ok(req.timedout)
res.end('Hello')
})

request(server)
.get('/')
.expect(503, /10ms/, done)
})
})

describe('req.getTimeout()', function () {
it('should get the correct timeout left', function (done) {
var server = createServer(null,
function (req, res) {
setTimeout(function () {
assert.ok(req.getTimeout() > 0 && req.getTimeout() < 100)
}, 50)
},
function (req, res) {
assert.equal(req.getTimeout(), 0)
res.end('Hello')
done()
})

request(server)
.get('/')
.expect(503, /100ms/, function () {})
})
it('should return 0 after clearTimeout', function (done) {
var server = createServer(null,
function (req, res) {
assert.ok(req.getTimeout() > 0)
req.clearTimeout()
assert.equal(req.getTimeout(), 0)
},
function (req, res) {
res.end('Hello')
})

request(server)
.get('/')
.expect(200, 'Hello', done)
})
})

describe('destroy()', function () {
it('req should clear timer', function (done) {
var server = createServer(null,
Expand Down