Skip to content

Commit

Permalink
quic: refactor/improve error handling for busy event
Browse files Browse the repository at this point in the history
Also, change setServerBusy into a setter

PR-URL: #34247
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
jasnell committed Jul 9, 2020
1 parent edc71ef commit cc89aac
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 21 deletions.
33 changes: 16 additions & 17 deletions doc/api/quic.md
Expand Up @@ -1330,8 +1330,8 @@ added: REPLACEME
-->

Emitted when the server busy state has been toggled using
`quicSocket.setServerBusy()`. The callback is invoked with a single
boolean argument indicating `true` if busy status is enabled,
`quicSocket.serverBusy = true | false`. The callback is invoked with a
single boolean argument indicating `true` if busy status is enabled,
`false` otherwise. This event is strictly informational.

```js
Expand All @@ -1346,8 +1346,8 @@ socket.on('busy', (busy) => {
console.log('Server is not busy');
});

socket.setServerBusy(true);
socket.setServerBusy(false);
socket.serverBusy = true;
socket.serverBusy = false;
```

This `'busy'` event may be emitted multiple times.
Expand Down Expand Up @@ -1874,6 +1874,18 @@ Set to `true` if the socket is not yet bound to the local UDP port.
added: REPLACEME
-->

#### quicsocket.serverBusy
<!-- YAML
added: REPLACEME
-->

* Type: {boolean} When `true`, the `QuicSocket` will reject new connections.

Setting `quicsocket.serverBusy` to `true` will tell the `QuicSocket`
to reject all new incoming connection requests using the `SERVER_BUSY` QUIC
error code. To begin receiving connections again, disable busy mode by setting
`quicsocket.serverBusy = false`.

#### quicsocket.serverBusyCount
<!-- YAML
added: REPLACEME
Expand Down Expand Up @@ -1911,19 +1923,6 @@ by artificially dropping received or transmitted packets.

This method is *not* to be used in production applications.

#### quicsocket.setServerBusy(\[on\])
<!-- YAML
added: REPLACEME
-->

* `on` {boolean} When `true`, the `QuicSocket` will reject new connections.
**Defaults**: `true`.

Calling `setServerBusy()` or `setServerBusy(true)` will tell the `QuicSocket`
to reject all new incoming connection requests using the `SERVER_BUSY` QUIC
error code. To begin receiving connections again, disable busy mode by calling
`setServerBusy(false)`.

#### quicsocket.statelessResetCount
<!-- YAML
added: REPLACEME
Expand Down
17 changes: 13 additions & 4 deletions lib/internal/quic/core.js
Expand Up @@ -851,7 +851,7 @@ class QuicSocket extends EventEmitter {
highWaterMark: undefined,
lookup: undefined,
server: undefined,
serverBusy: undefined,
serverBusy: false,
serverListening: false,
serverSecureContext: undefined,
sessions: new Set(),
Expand Down Expand Up @@ -1075,7 +1075,16 @@ class QuicSocket extends EventEmitter {
// Called by the C++ internals to notify when server busy status is toggled.
[kServerBusy](on) {
this[kInternalState].serverBusy = on;
process.nextTick(emit.bind(this, 'busy', on));
// In a nextTick because the event ends up being
// emitted synchronously when quicSocket.serverBusy
// is called.
process.nextTick(() => {
try {
this.emit('busy', on);
} catch (error) {
this[kRejections](error, 'busy', on);
}
});
}

addEndpoint(options = {}) {
Expand Down Expand Up @@ -1490,10 +1499,10 @@ class QuicSocket extends EventEmitter {

// Marking a server as busy will cause all new
// connection attempts to fail with a SERVER_BUSY CONNECTION_CLOSE.
setServerBusy(on = true) {
set serverBusy(on) {
const state = this[kInternalState];
if (state.state === kSocketDestroyed)
throw new ERR_QUICSOCKET_DESTROYED('setServerBusy');
throw new ERR_QUICSOCKET_DESTROYED('serverBusy');
validateBoolean(on, 'on');
if (state.serverBusy !== on)
this[kHandle].setServerBusy(on);
Expand Down
32 changes: 32 additions & 0 deletions test/parallel/test-quic-server-busy-event-error-async.js
@@ -0,0 +1,32 @@
// Flags: --no-warnings
'use strict';

const common = require('../common');
if (!common.hasQuic)
common.skip('missing quic');

const assert = require('assert');
const {
key,
cert,
ca,
} = require('../common/quic');

const { createQuicSocket } = require('net');

const options = { key, cert, ca, alpn: 'zzz' };

const server = createQuicSocket({ server: options });

server.on('busy', common.mustCall(async () => {
throw new Error('boom');
}));

server.on('close', common.mustCall());

server.on('error', common.mustCall((err) => {
assert.strictEqual(err.message, 'boom');
}));

assert.strictEqual(server.serverBusy, false);
server.serverBusy = true;
32 changes: 32 additions & 0 deletions test/parallel/test-quic-server-busy-event-error.js
@@ -0,0 +1,32 @@
// Flags: --no-warnings
'use strict';

const common = require('../common');
if (!common.hasQuic)
common.skip('missing quic');

const assert = require('assert');
const {
key,
cert,
ca,
} = require('../common/quic');

const { createQuicSocket } = require('net');

const options = { key, cert, ca, alpn: 'zzz' };

const server = createQuicSocket({ server: options });

server.on('busy', common.mustCall(() => {
throw new Error('boom');
}));

server.on('close', common.mustCall());

server.on('error', common.mustCall((err) => {
assert.strictEqual(err.message, 'boom');
}));

assert.strictEqual(server.serverBusy, false);
server.serverBusy = true;

0 comments on commit cc89aac

Please sign in to comment.