Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
quic: refactor/improve error handling for busy event
Also, change setServerBusy into a setter
  • Loading branch information
jasnell committed Jul 7, 2020
commit 7a16657d81e114948f9b2cee4242590857d9ae1e
33 changes: 16 additions & 17 deletions doc/api/quic.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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;