@kapeta/local-cluster-service 0.64.0 → 0.64.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/src/clusterService.d.ts +1 -1
- package/dist/cjs/src/clusterService.js +35 -37
- package/dist/cjs/src/storm/UIServer.d.ts +0 -8
- package/dist/cjs/src/storm/UIServer.js +8 -11
- package/dist/esm/src/clusterService.d.ts +1 -1
- package/dist/esm/src/clusterService.js +35 -37
- package/dist/esm/src/storm/UIServer.d.ts +0 -8
- package/dist/esm/src/storm/UIServer.js +8 -11
- package/package.json +1 -1
- package/src/clusterService.ts +29 -40
- package/src/storm/UIServer.ts +9 -22
- package/src/storm/routes.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.64.2](https://github.com/kapetacom/local-cluster-service/compare/v0.64.1...v0.64.2) (2024-08-22)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* handle port detection on multiple interfaces ([#222](https://github.com/kapetacom/local-cluster-service/issues/222)) ([6635cc2](https://github.com/kapetacom/local-cluster-service/commit/6635cc207355b2083edbb380f0ba83227c6a16e1))
|
7
|
+
|
8
|
+
## [0.64.1](https://github.com/kapetacom/local-cluster-service/compare/v0.64.0...v0.64.1) (2024-08-21)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* tweak port detection code ([#221](https://github.com/kapetacom/local-cluster-service/issues/221)) ([84000ea](https://github.com/kapetacom/local-cluster-service/commit/84000eae5eaec0d7ca975029b6cb7fcefcb87340))
|
14
|
+
|
1
15
|
# [0.64.0](https://github.com/kapetacom/local-cluster-service/compare/v0.63.1...v0.64.0) (2024-08-21)
|
2
16
|
|
3
17
|
|
@@ -16,7 +16,7 @@ declare class ClusterService {
|
|
16
16
|
* Gets next available port
|
17
17
|
*/
|
18
18
|
getNextAvailablePort(startPort?: number): Promise<number>;
|
19
|
-
|
19
|
+
private resolveWithAvailablePort;
|
20
20
|
/**
|
21
21
|
* The port of this local cluster service itself
|
22
22
|
*/
|
@@ -3,10 +3,13 @@
|
|
3
3
|
* Copyright 2023 Kapeta Inc.
|
4
4
|
* SPDX-License-Identifier: BUSL-1.1
|
5
5
|
*/
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
|
+
};
|
6
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
10
|
exports.clusterService = void 0;
|
8
11
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
9
|
-
const
|
12
|
+
const net_1 = __importDefault(require("net"));
|
10
13
|
const DEFAULT_SERVER_PORT = 35100;
|
11
14
|
const DEFAULT_START_PORT = 40000;
|
12
15
|
const DEFAULT_HOST = '127.0.0.1';
|
@@ -38,56 +41,51 @@ class ClusterService {
|
|
38
41
|
await this._findClusterServicePort();
|
39
42
|
}
|
40
43
|
async _findClusterServicePort() {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
for (; this._port <= 65535; this._port++) {
|
45
|
+
try {
|
46
|
+
await this.resolveWithAvailablePort(this._port);
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
catch (e) {
|
50
|
+
// try again
|
45
51
|
}
|
46
|
-
this._port++;
|
47
52
|
}
|
53
|
+
throw new Error('No available ports');
|
48
54
|
}
|
49
55
|
/**
|
50
56
|
* Gets next available port
|
51
57
|
*/
|
52
58
|
async getNextAvailablePort(startPort = -1) {
|
53
|
-
let
|
54
|
-
|
55
|
-
|
56
|
-
}
|
57
|
-
while (true) {
|
58
|
-
while (this._reservedPorts.indexOf(startPort) > -1) {
|
59
|
-
startPort++;
|
60
|
-
if (!receivedStartPort) {
|
61
|
-
this._currentPort = startPort;
|
62
|
-
}
|
63
|
-
}
|
64
|
-
const nextPort = startPort++;
|
65
|
-
if (!receivedStartPort) {
|
66
|
-
this._currentPort = startPort;
|
59
|
+
for (let nextPort = startPort > 0 ? startPort : this._currentPort; nextPort <= 65535; nextPort++) {
|
60
|
+
if (this._reservedPorts.indexOf(nextPort) > -1) {
|
61
|
+
continue;
|
67
62
|
}
|
68
|
-
|
69
|
-
|
63
|
+
try {
|
64
|
+
// Try both IPv4 and IPv6 addresses
|
65
|
+
await this.resolveWithAvailablePort(nextPort);
|
66
|
+
await this.resolveWithAvailablePort(nextPort, '0.0.0.0');
|
67
|
+
// Save the state if we're looking for a system port for the cluster itself
|
68
|
+
if (startPort <= 0) {
|
69
|
+
this._currentPort = nextPort;
|
70
|
+
}
|
70
71
|
return nextPort;
|
71
72
|
}
|
73
|
+
catch (e) {
|
74
|
+
// try again }
|
75
|
+
}
|
72
76
|
}
|
77
|
+
throw new Error('No available ports');
|
73
78
|
}
|
74
|
-
|
79
|
+
async resolveWithAvailablePort(port, host = this._host) {
|
75
80
|
return new Promise((resolve, reject) => {
|
76
|
-
const server =
|
77
|
-
server.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
}
|
83
|
-
server.close();
|
84
|
-
reject(err);
|
85
|
-
});
|
86
|
-
server.once('listening', function () {
|
87
|
-
server.close();
|
88
|
-
resolve(false);
|
81
|
+
const server = net_1.default.createServer();
|
82
|
+
server.unref();
|
83
|
+
server.on('error', reject);
|
84
|
+
server.listen({ port, host }, (...args) => {
|
85
|
+
server.close(() => {
|
86
|
+
resolve(port);
|
87
|
+
});
|
89
88
|
});
|
90
|
-
server.listen(port, host);
|
91
89
|
});
|
92
90
|
}
|
93
91
|
/**
|
@@ -1,13 +1,5 @@
|
|
1
|
-
/// <reference types="node" />
|
2
|
-
import { Server } from 'http';
|
3
1
|
import { StormEventPage } from './events';
|
4
|
-
declare module 'express-serve-static-core' {
|
5
|
-
interface Application {
|
6
|
-
listen(port: number, callback?: (err?: Error) => void): Server;
|
7
|
-
}
|
8
|
-
}
|
9
2
|
export declare class UIServer {
|
10
|
-
private readonly express;
|
11
3
|
private readonly systemId;
|
12
4
|
private port;
|
13
5
|
private server;
|
@@ -11,34 +11,31 @@ exports.UIServer = void 0;
|
|
11
11
|
const express_1 = __importDefault(require("express"));
|
12
12
|
const page_utils_1 = require("./page-utils");
|
13
13
|
const clusterService_1 = require("../clusterService");
|
14
|
+
const http_1 = require("http");
|
14
15
|
class UIServer {
|
15
|
-
express;
|
16
16
|
systemId;
|
17
17
|
port = 50000;
|
18
18
|
server;
|
19
19
|
constructor(systemId) {
|
20
20
|
this.systemId = systemId;
|
21
|
-
this.express = (0, express_1.default)();
|
22
21
|
}
|
23
22
|
async start() {
|
24
|
-
|
25
|
-
|
23
|
+
const app = (0, express_1.default)();
|
24
|
+
app.get('/_reset', (req, res) => {
|
26
25
|
res.send(`
|
27
26
|
<script>
|
28
27
|
window.localStorage.clear();
|
29
28
|
window.sessionStorage.clear();
|
30
29
|
</script>`);
|
31
30
|
});
|
32
|
-
|
31
|
+
app.all('/*', (req, res) => {
|
33
32
|
(0, page_utils_1.readPageFromDisk)(this.systemId, req.params[0], req.method, res);
|
34
33
|
});
|
34
|
+
this.port = await clusterService_1.clusterService.getNextAvailablePort(this.port);
|
35
35
|
return new Promise((resolve, reject) => {
|
36
|
-
this.server =
|
37
|
-
|
38
|
-
|
39
|
-
reject(err);
|
40
|
-
return;
|
41
|
-
}
|
36
|
+
this.server = (0, http_1.createServer)(app);
|
37
|
+
this.server.on('error', reject);
|
38
|
+
this.server.listen(this.port, () => {
|
42
39
|
console.log(`UI Server started on port ${this.port}`);
|
43
40
|
resolve();
|
44
41
|
});
|
@@ -16,7 +16,7 @@ declare class ClusterService {
|
|
16
16
|
* Gets next available port
|
17
17
|
*/
|
18
18
|
getNextAvailablePort(startPort?: number): Promise<number>;
|
19
|
-
|
19
|
+
private resolveWithAvailablePort;
|
20
20
|
/**
|
21
21
|
* The port of this local cluster service itself
|
22
22
|
*/
|
@@ -3,10 +3,13 @@
|
|
3
3
|
* Copyright 2023 Kapeta Inc.
|
4
4
|
* SPDX-License-Identifier: BUSL-1.1
|
5
5
|
*/
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
|
+
};
|
6
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
10
|
exports.clusterService = void 0;
|
8
11
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
9
|
-
const
|
12
|
+
const net_1 = __importDefault(require("net"));
|
10
13
|
const DEFAULT_SERVER_PORT = 35100;
|
11
14
|
const DEFAULT_START_PORT = 40000;
|
12
15
|
const DEFAULT_HOST = '127.0.0.1';
|
@@ -38,56 +41,51 @@ class ClusterService {
|
|
38
41
|
await this._findClusterServicePort();
|
39
42
|
}
|
40
43
|
async _findClusterServicePort() {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
for (; this._port <= 65535; this._port++) {
|
45
|
+
try {
|
46
|
+
await this.resolveWithAvailablePort(this._port);
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
catch (e) {
|
50
|
+
// try again
|
45
51
|
}
|
46
|
-
this._port++;
|
47
52
|
}
|
53
|
+
throw new Error('No available ports');
|
48
54
|
}
|
49
55
|
/**
|
50
56
|
* Gets next available port
|
51
57
|
*/
|
52
58
|
async getNextAvailablePort(startPort = -1) {
|
53
|
-
let
|
54
|
-
|
55
|
-
|
56
|
-
}
|
57
|
-
while (true) {
|
58
|
-
while (this._reservedPorts.indexOf(startPort) > -1) {
|
59
|
-
startPort++;
|
60
|
-
if (!receivedStartPort) {
|
61
|
-
this._currentPort = startPort;
|
62
|
-
}
|
63
|
-
}
|
64
|
-
const nextPort = startPort++;
|
65
|
-
if (!receivedStartPort) {
|
66
|
-
this._currentPort = startPort;
|
59
|
+
for (let nextPort = startPort > 0 ? startPort : this._currentPort; nextPort <= 65535; nextPort++) {
|
60
|
+
if (this._reservedPorts.indexOf(nextPort) > -1) {
|
61
|
+
continue;
|
67
62
|
}
|
68
|
-
|
69
|
-
|
63
|
+
try {
|
64
|
+
// Try both IPv4 and IPv6 addresses
|
65
|
+
await this.resolveWithAvailablePort(nextPort);
|
66
|
+
await this.resolveWithAvailablePort(nextPort, '0.0.0.0');
|
67
|
+
// Save the state if we're looking for a system port for the cluster itself
|
68
|
+
if (startPort <= 0) {
|
69
|
+
this._currentPort = nextPort;
|
70
|
+
}
|
70
71
|
return nextPort;
|
71
72
|
}
|
73
|
+
catch (e) {
|
74
|
+
// try again }
|
75
|
+
}
|
72
76
|
}
|
77
|
+
throw new Error('No available ports');
|
73
78
|
}
|
74
|
-
|
79
|
+
async resolveWithAvailablePort(port, host = this._host) {
|
75
80
|
return new Promise((resolve, reject) => {
|
76
|
-
const server =
|
77
|
-
server.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
}
|
83
|
-
server.close();
|
84
|
-
reject(err);
|
85
|
-
});
|
86
|
-
server.once('listening', function () {
|
87
|
-
server.close();
|
88
|
-
resolve(false);
|
81
|
+
const server = net_1.default.createServer();
|
82
|
+
server.unref();
|
83
|
+
server.on('error', reject);
|
84
|
+
server.listen({ port, host }, (...args) => {
|
85
|
+
server.close(() => {
|
86
|
+
resolve(port);
|
87
|
+
});
|
89
88
|
});
|
90
|
-
server.listen(port, host);
|
91
89
|
});
|
92
90
|
}
|
93
91
|
/**
|
@@ -1,13 +1,5 @@
|
|
1
|
-
/// <reference types="node" />
|
2
|
-
import { Server } from 'http';
|
3
1
|
import { StormEventPage } from './events';
|
4
|
-
declare module 'express-serve-static-core' {
|
5
|
-
interface Application {
|
6
|
-
listen(port: number, callback?: (err?: Error) => void): Server;
|
7
|
-
}
|
8
|
-
}
|
9
2
|
export declare class UIServer {
|
10
|
-
private readonly express;
|
11
3
|
private readonly systemId;
|
12
4
|
private port;
|
13
5
|
private server;
|
@@ -11,34 +11,31 @@ exports.UIServer = void 0;
|
|
11
11
|
const express_1 = __importDefault(require("express"));
|
12
12
|
const page_utils_1 = require("./page-utils");
|
13
13
|
const clusterService_1 = require("../clusterService");
|
14
|
+
const http_1 = require("http");
|
14
15
|
class UIServer {
|
15
|
-
express;
|
16
16
|
systemId;
|
17
17
|
port = 50000;
|
18
18
|
server;
|
19
19
|
constructor(systemId) {
|
20
20
|
this.systemId = systemId;
|
21
|
-
this.express = (0, express_1.default)();
|
22
21
|
}
|
23
22
|
async start() {
|
24
|
-
|
25
|
-
|
23
|
+
const app = (0, express_1.default)();
|
24
|
+
app.get('/_reset', (req, res) => {
|
26
25
|
res.send(`
|
27
26
|
<script>
|
28
27
|
window.localStorage.clear();
|
29
28
|
window.sessionStorage.clear();
|
30
29
|
</script>`);
|
31
30
|
});
|
32
|
-
|
31
|
+
app.all('/*', (req, res) => {
|
33
32
|
(0, page_utils_1.readPageFromDisk)(this.systemId, req.params[0], req.method, res);
|
34
33
|
});
|
34
|
+
this.port = await clusterService_1.clusterService.getNextAvailablePort(this.port);
|
35
35
|
return new Promise((resolve, reject) => {
|
36
|
-
this.server =
|
37
|
-
|
38
|
-
|
39
|
-
reject(err);
|
40
|
-
return;
|
41
|
-
}
|
36
|
+
this.server = (0, http_1.createServer)(app);
|
37
|
+
this.server.on('error', reject);
|
38
|
+
this.server.listen(this.port, () => {
|
42
39
|
console.log(`UI Server started on port ${this.port}`);
|
43
40
|
resolve();
|
44
41
|
});
|
package/package.json
CHANGED
package/src/clusterService.ts
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
import { normalizeKapetaUri } from '@kapeta/nodejs-utils';
|
7
7
|
|
8
|
-
|
8
|
+
import net from 'net';
|
9
9
|
const DEFAULT_SERVER_PORT = 35100;
|
10
10
|
const DEFAULT_START_PORT = 40000;
|
11
11
|
const DEFAULT_HOST = '127.0.0.1';
|
@@ -44,64 +44,53 @@ class ClusterService {
|
|
44
44
|
}
|
45
45
|
|
46
46
|
async _findClusterServicePort() {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
for (; this._port <= 65535; this._port++) {
|
48
|
+
try {
|
49
|
+
await this.resolveWithAvailablePort(this._port);
|
50
|
+
return;
|
51
|
+
} catch (e) {
|
52
|
+
// try again
|
51
53
|
}
|
52
|
-
|
53
|
-
this._port++;
|
54
54
|
}
|
55
|
+
throw new Error('No available ports');
|
55
56
|
}
|
56
57
|
|
57
58
|
/**
|
58
59
|
* Gets next available port
|
59
60
|
*/
|
60
61
|
public async getNextAvailablePort(startPort: number = -1) {
|
61
|
-
let
|
62
|
-
|
63
|
-
|
64
|
-
}
|
65
|
-
while (true) {
|
66
|
-
while (this._reservedPorts.indexOf(startPort) > -1) {
|
67
|
-
startPort++;
|
68
|
-
if (!receivedStartPort) {
|
69
|
-
this._currentPort = startPort;
|
70
|
-
}
|
62
|
+
for (let nextPort = startPort > 0 ? startPort : this._currentPort; nextPort <= 65535; nextPort++) {
|
63
|
+
if (this._reservedPorts.indexOf(nextPort) > -1) {
|
64
|
+
continue;
|
71
65
|
}
|
72
66
|
|
73
|
-
|
74
|
-
|
75
|
-
this.
|
76
|
-
|
77
|
-
|
78
|
-
|
67
|
+
try {
|
68
|
+
// Try both IPv4 and IPv6 addresses
|
69
|
+
await this.resolveWithAvailablePort(nextPort);
|
70
|
+
await this.resolveWithAvailablePort(nextPort, '0.0.0.0');
|
71
|
+
// Save the state if we're looking for a system port for the cluster itself
|
72
|
+
if (startPort <= 0) {
|
73
|
+
this._currentPort = nextPort;
|
74
|
+
}
|
79
75
|
return nextPort;
|
76
|
+
} catch (e) {
|
77
|
+
// try again }
|
80
78
|
}
|
81
79
|
}
|
80
|
+
throw new Error('No available ports');
|
82
81
|
}
|
83
82
|
|
84
|
-
|
83
|
+
private async resolveWithAvailablePort(port: number, host: string = this._host) {
|
85
84
|
return new Promise((resolve, reject) => {
|
86
85
|
const server = net.createServer();
|
86
|
+
server.unref();
|
87
|
+
server.on('error', reject);
|
87
88
|
|
88
|
-
server.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
return;
|
93
|
-
}
|
94
|
-
|
95
|
-
server.close();
|
96
|
-
reject(err);
|
89
|
+
server.listen({ port, host }, (...args) => {
|
90
|
+
server.close(() => {
|
91
|
+
resolve(port);
|
92
|
+
});
|
97
93
|
});
|
98
|
-
|
99
|
-
server.once('listening', function () {
|
100
|
-
server.close();
|
101
|
-
resolve(false);
|
102
|
-
});
|
103
|
-
|
104
|
-
server.listen(port, host);
|
105
94
|
});
|
106
95
|
}
|
107
96
|
|
package/src/storm/UIServer.ts
CHANGED
@@ -5,20 +5,10 @@
|
|
5
5
|
import express, { Express, Request, Response } from 'express';
|
6
6
|
import { readPageFromDisk } from './page-utils';
|
7
7
|
import { clusterService } from '../clusterService';
|
8
|
-
import { Server } from 'http';
|
8
|
+
import { createServer, Server } from 'http';
|
9
9
|
import { StormEventPage } from './events';
|
10
10
|
|
11
|
-
declare module 'express-serve-static-core' {
|
12
|
-
interface Application {
|
13
|
-
// Adds error callback support
|
14
|
-
// From the docs:
|
15
|
-
// All the forms of Node’s http.Server.listen() method are in fact actually supported.
|
16
|
-
listen(port: number, callback?: (err?: Error) => void): Server;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
11
|
export class UIServer {
|
21
|
-
private readonly express: Express;
|
22
12
|
private readonly systemId: string;
|
23
13
|
|
24
14
|
private port: number = 50000;
|
@@ -26,13 +16,11 @@ export class UIServer {
|
|
26
16
|
|
27
17
|
constructor(systemId: string) {
|
28
18
|
this.systemId = systemId;
|
29
|
-
this.express = express();
|
30
19
|
}
|
31
20
|
|
32
21
|
public async start() {
|
33
|
-
|
34
|
-
|
35
|
-
this.express.get('/_reset', (req: Request, res: Response) => {
|
22
|
+
const app = express();
|
23
|
+
app.get('/_reset', (req: Request, res: Response) => {
|
36
24
|
res.send(
|
37
25
|
`
|
38
26
|
<script>
|
@@ -42,17 +30,16 @@ export class UIServer {
|
|
42
30
|
);
|
43
31
|
});
|
44
32
|
|
45
|
-
|
33
|
+
app.all('/*', (req: Request, res: Response) => {
|
46
34
|
readPageFromDisk(this.systemId, req.params[0], req.method, res);
|
47
35
|
});
|
48
36
|
|
37
|
+
this.port = await clusterService.getNextAvailablePort(this.port);
|
49
38
|
return new Promise<void>((resolve, reject) => {
|
50
|
-
this.server =
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
return;
|
55
|
-
}
|
39
|
+
this.server = createServer(app);
|
40
|
+
this.server.on('error', reject);
|
41
|
+
|
42
|
+
this.server.listen(this.port, () => {
|
56
43
|
console.log(`UI Server started on port ${this.port}`);
|
57
44
|
resolve();
|
58
45
|
});
|
package/src/storm/routes.ts
CHANGED