Skip to content

Commit

Permalink
Further WebSocket enhancements along with other corrections, touch #456.
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulDalek committed Jun 12, 2024
1 parent 832697e commit 8f88732
Show file tree
Hide file tree
Showing 18 changed files with 492 additions and 335 deletions.
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ WEB_SOCKET_ENABLE = false
WEB_SOCKET_RECONNECT = false
WEB_SOCKET_REJECT_UNAUTHORIZED = false
WEB_SOCKET_PING_TIMEOUT = 16000
WEB_SOCKET_RECONNECT_ATTEMPTS = 3
WEB_SOCKET_RECONNECT_INTERVAL = 3000
WEB_SOCKET_RECONNECT_ATTEMPTS = 3
WEB_SOCKET_URL =
WEB_SOCKET_SECRET =
10 changes: 2 additions & 8 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ module.exports = {
}
],
rules: {
'no-unused-vars': 0,
'import/no-cycle': 2,
'prettier/prettier': [
'error',
{
endOfLine: require('os').EOL === '\r\n' ? 'crlf' : 'lf'
}
]
'no-unused-vars': 'off',
'import/no-cycle': 'error'
}
};
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,17 @@ These variables are set in your environment and take precedence over options fro
- `DEBUG_SLOW_MO`: Slows down Puppeteer operations by the specified number of milliseconds (defaults to `0`).
- `DEBUG_DEBUGGING_PORT`: Specifies the debugging port (defaults to `9222`).

### WebSocket Config

- `WEB_SOCKET_ENABLE`: Enables or disables the WebSocket connection (defaults to `false`).
- `WEB_SOCKET_RECONNECT`: Controls whether or not to try reconnecting to the WebSocket server in case of a disconnect (defaults to `false`).
- `WEB_SOCKET_REJECT_UNAUTHORIZED`: Determines whether the client verifies the server's SSL/TLS certificate during the handshake process (defaults to `false`).
- `WEB_SOCKET_PING_TIMEOUT`: The timeout, in milliseconds, for the heartbeat mechanism between the client and server (defaults to `16000`).
- `WEB_SOCKET_RECONNECT_INTERVAL`: The interval, in milliseconds, for the reconnect attempt (defaults to `3000`).
- `WEB_SOCKET_RECONNECT_ATTEMPTS`: The number of reconnect attempts before returning a connection error (defaults to `3`).
- `WEB_SOCKET_URL`: The URL of the WebSocket server (defaults to ``).
- `WEB_SOCKET_SECRET`: The secret used to create a JSON Web Token sent to the WebSocket server (defaults to ``).

## Command Line Arguments

To supply command line arguments, add them as flags when running the application:
Expand Down Expand Up @@ -448,6 +459,14 @@ _Available options:_
- `--dumpio`: Redirects browser process stdout and stderr to process.stdout and process.stderr (defaults to `false`).
- `--slowMo`: Slows down Puppeteer operations by the specified number of milliseconds (defaults to `0`).
- `--debuggingPort`: Specifies the debugging port (defaults to `9222`).
- `--enableWs`: Enables or disables the WebSocket connection (defaults to `false`).
- `--wsReconnect`: Controls whether or not to try reconnecting to the WebSocket server in case of a disconnect (defaults to `false`).
- `--wsrejectUnauthorized`: Determines whether the client verifies the server's SSL/TLS certificate during the handshake process (defaults to `false`).
- `--wsPingTimeout`: The timeout, in milliseconds, for the heartbeat mechanism between the client and server (defaults to `16000`).
- `--wsReconnectInterval`: The interval, in milliseconds, for the reconnect attempt (defaults to `3000`).
- `--wsReconnectAttempts`: The number of reconnect attempts before returning a connection error (defaults to `3`).
- `--wsUrl`: The URL of the WebSocket server (defaults to ``).
- `--wsSecret`: The secret used to create a JSON Web Token sent to the WebSocket server (defaults to ``).

# HTTP Server

Expand Down
4 changes: 2 additions & 2 deletions dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.esm.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions lib/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ export default async (page, chart, options) => {
// eslint-disable-next-line no-undef
const { chartHeight, chartWidth } = window.Highcharts.charts[0];

// No need for such scale manipulation in case of other types of exports
// Reset the zoom for other exports than to SVGs
// No need for such scale manipulation in case of other types
// of exports. Reset the zoom for other exports than to SVGs
// eslint-disable-next-line no-undef
document.body.style.zoom = 1;

Expand Down
42 changes: 0 additions & 42 deletions lib/intervals.js

This file was deleted.

9 changes: 8 additions & 1 deletion lib/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,19 @@ export function getPoolInfo() {
log(5, `[pool] The number of resources waiting to be acquired: ${pending}.`);
}

/**
* Gets the statistic of a pool instace about exports.
*/
export function getStats() {
return stats;
}

export default {
initPool,
killPool,
postWork,
getPool,
getPoolInfo,
getPoolInfoJSON,
getStats: () => stats
getStats
};
10 changes: 7 additions & 3 deletions lib/resource_release.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ See LICENSE file in root for details.
*******************************************************************************/

import { clearAllIntervals } from './intervals.js';
import { clearAllTimers } from './timers.js';
import { killPool } from './pool.js';
import { closeServers } from './server/server.js';
import { terminateClients } from './server/web_socket.js';

/**
* Clean up function to trigger before ending process for the graceful shutdown.
Expand All @@ -24,8 +25,11 @@ import { closeServers } from './server/server.js';
export const shutdownCleanUp = async (exitCode) => {
// Await freeing all resources
await Promise.allSettled([
// Clear all ongoing intervals
clearAllIntervals(),
// Clear all ongoing timers
clearAllTimers(),

// Terminate all connected WebSocket clients
terminateClients(),

// Get available server instances (HTTP/HTTPS) and close them
closeServers(),
Expand Down
113 changes: 113 additions & 0 deletions lib/schemas/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,69 @@ export const defaultConfig = {
envLink: 'DEBUG_DEBUGGING_PORT',
description: 'Specifies the debugging port.'
}
},
webSocket: {
enable: {
value: false,
type: 'boolean',
envLink: 'WEB_SOCKET_ENABLE',
cliName: 'enableWs',
description: 'Enables or disables the WebSocket connection.'
},
reconnect: {
value: false,
type: 'boolean',
envLink: 'WEB_SOCKET_RECONNECT',
cliName: 'wsReconnect',
description:
'Controls whether or not to try reconnecting to the WebSocket server in case of a disconnect.'
},
rejectUnauthorized: {
value: false,
type: 'boolean',
envLink: 'WEB_SOCKET_REJECT_UNAUTHORIZED',
cliName: 'wsrejectUnauthorized',
description:
"Determines whether the client verifies the server's SSL/TLS certificate during the handshake process."
},
pingTimeout: {
value: 16000,
type: 'number',
envLink: 'WEB_SOCKET_PING_TIMEOUT',
cliName: 'wsPingTimeout',
description:
'The timeout, in milliseconds, for the heartbeat mechanism between the client and server.'
},
reconnectInterval: {
value: 3000,
type: 'number',
envLink: 'WEB_SOCKET_RECONNECT_INTERVAL',
cliName: 'wsReconnectInterval',
description: 'The interval, in milliseconds, for the reconnect attempt.'
},
reconnectAttempts: {
value: 3,
type: 'number',
envLink: 'WEB_SOCKET_RECONNECT_ATTEMPTS',
cliName: 'wsReconnectAttempts',
description:
'The number of reconnect attempts before returning a connection error.'
},
url: {
value: false,
type: 'string',
envLink: 'WEB_SOCKET_URL',
cliName: 'wsUrl',
description: 'The URL of the WebSocket server.'
},
secret: {
value: false,
type: 'string',
envLink: 'WEB_SOCKET_SECRET',
cliName: 'wsSecret',
description:
'The secret used to create a JSON Web Token sent to the WebSocket server.'
}
}
};

Expand Down Expand Up @@ -1097,6 +1160,56 @@ export const promptsConfig = {
message: 'The port number for debugging',
initial: defaultConfig.debug.debuggingPort.value
}
],
webSocket: [
{
type: 'toggle',
name: 'enable',
message: 'Enables WebSocket connection',
initial: defaultConfig.webSocket.enable.value
},
{
type: 'toggle',
name: 'reconnect',
message: 'The reconnect mechanism for WebSocket connection',
initial: defaultConfig.webSocket.reconnect.value
},
{
type: 'toggle',
name: 'rejectUnauthorized',
message: 'Reject connection if WebSocket is not secured, SSL/TLS',
initial: defaultConfig.webSocket.rejectUnauthorized.value
},
{
type: 'number',
name: 'pingTimeout',
message: 'Timeout for the hearbeat mechanism',
initial: defaultConfig.webSocket.pingTimeout.value
},
{
type: 'number',
name: 'reconnectInterval',
message: 'Interval for the reconnect mechanism',
initial: defaultConfig.webSocket.reconnectInterval.value
},
{
type: 'number',
name: 'reconnectAttempts',
message: 'The number of reconnect attempts',
initial: defaultConfig.webSocket.reconnectAttempts.value
},
{
type: 'text',
name: 'url',
message: 'The URL of the WebSocket server',
initial: defaultConfig.webSocket.url.value
},
{
type: 'text',
name: 'secret',
message: 'The secret for the JWT to WebSocket server',
initial: defaultConfig.webSocket.secret.value
}
]
};

Expand Down
2 changes: 1 addition & 1 deletion lib/server/routes/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const exportHandler = async (request, response, next) => {
const defaultOptions = getOptions();

// Get the first WebSocket client
const webSocketClient = getWebSocketClient().values().next().value;
const webSocketClient = getWebSocketClient().next().value;

const body = request.body;
const id = ++requestsCounter;
Expand Down
12 changes: 6 additions & 6 deletions lib/server/routes/health.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { join as pather } from 'path';
import { log } from '../../logger.js';

import { version } from '../../cache.js';
import { addInterval } from '../../intervals.js';
import pool from '../../pool.js';
import { addTimer } from '../../timers.js';
import { getStats, getPoolInfoJSON } from '../../pool.js';
import { __dirname } from '../../utils.js';

const pkgFile = JSON.parse(readFileSync(pather(__dirname, 'package.json')));
Expand Down Expand Up @@ -48,7 +48,7 @@ function calculateMovingAverage() {
*/
export const startSuccessRate = () =>
setInterval(() => {
const stats = pool.getStats();
const stats = getStats();
const successRatio =
stats.exportAttempts === 0
? 1
Expand All @@ -71,10 +71,10 @@ export default function addHealthRoutes(app) {

// Start processing success rate ratio interval and save its id to the array
// for the graceful clearing on shutdown with injected addInterval funtion
addInterval(startSuccessRate());
addTimer(startSuccessRate());

app.get('/health', (_, res) => {
const stats = pool.getStats();
const stats = getStats();
const period = successRates.length;
const movingAverage = calculateMovingAverage();

Expand All @@ -95,7 +95,7 @@ export default function addHealthRoutes(app) {
exportAttempts: stats.exportAttempts,
sucessRatio: (stats.performedExports / stats.exportAttempts) * 100,
// eslint-disable-next-line import/no-named-as-default-member
pool: pool.getPoolInfoJSON(),
pool: getPoolInfoJSON(),

// Moving average
period,
Expand Down
Loading

0 comments on commit 8f88732

Please sign in to comment.