Skip to content

Commit c3a1f84

Browse files
committed
request.active(). Closes hapijs#3827
1 parent 1853275 commit c3a1f84

File tree

5 files changed

+85
-4
lines changed

5 files changed

+85
-4
lines changed

API.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# v17.5.x API Reference
1+
# v17.6.x API Reference
22

33
<!-- toc -->
44

@@ -238,6 +238,7 @@
238238
- [`request.server`](#request.server)
239239
- [`request.state`](#request.state)
240240
- [`request.url`](#request.url)
241+
- [`request.active()`](#request.active())
241242
- [`request.generateResponse(source, [options])`](#request.generateResponse())
242243
- [`request.log(tags, [data])`](#request.log())
243244
- [`request.route.auth.access(request)`](#request.route.auth.access())
@@ -4795,6 +4796,36 @@ Returns a [`response`](#response-object) which you can pass into the [reply inte
47954796
- `response` - the response object being marshaled.
47964797
- should not throw errors (which are logged but otherwise ignored).
47974798

4799+
### <a name="request.active()" /> `request.active()`
4800+
4801+
Returns `true` when the request is active and processing should continue and `false` when the
4802+
request terminated early or completed its lifecycle. Useful when request processing is a
4803+
resource-intensive operation and should be terminated early if the request is no longer active
4804+
(e.g. client disconnected or aborted early).
4805+
4806+
```js
4807+
const Hapi = require('hapi');
4808+
const server = Hapi.server({ port: 80 });
4809+
4810+
server.route({
4811+
method: 'POST',
4812+
path: '/worker',
4813+
handler: function (request, h) {
4814+
4815+
// Do some work...
4816+
4817+
// Check if request is still active
4818+
if (!request.active()) {
4819+
return h.close;
4820+
}
4821+
4822+
// Do some more work...
4823+
4824+
return null;
4825+
}
4826+
});
4827+
```
4828+
47984829
### <a name="request.log()" /> `request.log(tags, [data])`
47994830

48004831
Logs request-specific events. When called, the server emits a [`'request'` event](#server.events.request)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ developers to focus on writing reusable application logic in a highly modular an
1010

1111
Version 17.x only supports node v8.9.0 and over. For older version of node please use version 16.x.
1212

13-
Development version: **17.5.x** ([release notes](https://github.com/hapijs/hapi/issues?labels=release+notes&page=1&state=closed))
13+
Development version: **17.6.x** ([release notes](https://github.com/hapijs/hapi/issues?labels=release+notes&page=1&state=closed))
1414
[![Linux Build Status](https://secure.travis-ci.org/hapijs/hapi.svg?branch=master)](https://travis-ci.org/hapijs/hapi)
1515
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/hapijs/hapi?branch=master&svg=true)](https://ci.appveyor.com/project/hueniverse/hapi)
1616

lib/request.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ exports = module.exports = internals.Request = class {
148148
this.method = method.toLowerCase();
149149
}
150150

151+
active() {
152+
153+
return !!this._eventContext.request;
154+
}
155+
151156
async _execute() {
152157

153158
this.info.acceptEncoding = this._core.compression.accept(this);
@@ -329,7 +334,9 @@ exports = module.exports = internals.Request = class {
329334

330335
await this._postCycle();
331336

332-
if (typeof this.response === 'symbol') { // close or abandon
337+
if (!this._eventContext.request ||
338+
typeof this.response === 'symbol') { // close or abandon
339+
333340
this._abort();
334341
return;
335342
}

npm-shrinkwrap.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/request.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,49 @@ describe('Request', () => {
211211
expect(res3.result).to.match(/10$/);
212212
});
213213

214+
describe('active()', () => {
215+
216+
it('exits handler early when request is no longer active', async () => {
217+
218+
const server = Hapi.server();
219+
const team = new Teamwork();
220+
221+
let rounds = 0;
222+
server.route({
223+
method: 'GET',
224+
path: '/',
225+
options: {
226+
handler: async (request, h) => {
227+
228+
for (let i = 0; i < 10; ++i) {
229+
++rounds;
230+
await Hoek.wait(10);
231+
232+
if (!request.active()) {
233+
break;
234+
}
235+
}
236+
237+
team.attend();
238+
return null;
239+
}
240+
}
241+
});
242+
243+
await server.start();
244+
245+
const req = Http.get(server.info.uri, (res) => { });
246+
req.on('error', Hoek.ignore);
247+
248+
await Hoek.wait(50);
249+
req.abort();
250+
await server.stop();
251+
252+
await team.work;
253+
expect(rounds).to.equal(5);
254+
});
255+
});
256+
214257
describe('_execute()', () => {
215258

216259
it('returns 400 on invalid path', async () => {

0 commit comments

Comments
 (0)