@hydranium/client-theia 1.0.0-next.270 → 1.0.0-next.271
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/lib/browser/connection-diagnostics-contribution.d.ts +6 -2
- package/lib/browser/connection-diagnostics-contribution.d.ts.map +1 -1
- package/lib/browser/connection-diagnostics-contribution.js +17 -8
- package/lib/browser/connection-diagnostics-contribution.js.map +1 -1
- package/lib/node/session-bound-frontend-connection-service.d.ts +8 -4
- package/lib/node/session-bound-frontend-connection-service.d.ts.map +1 -1
- package/lib/node/session-bound-frontend-connection-service.js +22 -10
- package/lib/node/session-bound-frontend-connection-service.js.map +1 -1
- package/package.json +3 -3
- package/src/browser/connection-diagnostics-contribution.ts +13 -9
- package/src/node/session-bound-frontend-connection-service.ts +16 -12
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
+
import { type Stopwatch } from '@hydranium/protocol';
|
|
9
10
|
import { MessageService } from '@theia/core';
|
|
10
11
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application-contribution';
|
|
11
12
|
import { ConnectionStatus, ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';
|
|
12
13
|
import { WebSocketConnectionSource } from '@theia/core/lib/browser/messaging/ws-connection-source';
|
|
13
14
|
import { type interfaces } from '@theia/core/shared/inversify';
|
|
15
|
+
import { Clock } from '../common/clock';
|
|
14
16
|
import { type ConnectionBufferOverflow } from '../common/framed-socket-write-buffer';
|
|
15
17
|
import { ChannelLogger } from './channel-logger';
|
|
16
18
|
/**
|
|
@@ -32,10 +34,12 @@ export declare class ConnectionDiagnosticsContribution implements FrontendApplic
|
|
|
32
34
|
protected readonly connectionStatus: ConnectionStatusService;
|
|
33
35
|
protected readonly logger: ChannelLogger;
|
|
34
36
|
protected readonly messageService: MessageService;
|
|
37
|
+
/** Times the outages the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
38
|
+
protected readonly clock: Clock;
|
|
35
39
|
/** Main channels created so far; more than one means the server did not recognise this frontend. */
|
|
36
40
|
protected channelCount: number;
|
|
37
|
-
protected
|
|
38
|
-
protected
|
|
41
|
+
protected sinceSocketClosed?: Stopwatch;
|
|
42
|
+
protected sinceOffline?: Stopwatch;
|
|
39
43
|
initialize(): void;
|
|
40
44
|
protected handleSocketOpen(): void;
|
|
41
45
|
protected handleSocketClose(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-diagnostics-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAO,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC9G,OAAO,EAAE,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AACnG,OAAO,
|
|
1
|
+
{"version":3,"file":"connection-diagnostics-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAO,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC9G,OAAO,EAAE,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AACnG,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;;;;;;;;;;GAaG;AACH,qBACa,iCAAkC,YAAW,+BAA+B;IACnD,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;IACjE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAC1E,4FAA4F;IACjE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAqB;IAE/E,oGAAoG;IACpG,SAAS,CAAC,YAAY,SAAK;IAC3B,SAAS,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IACxC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAEnC,UAAU,IAAI,IAAI,CAWjB;IAED,SAAS,CAAC,gBAAgB,IAAI,IAAI,CAIjC;IAED,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAGlC;IAED;;;;OAIG;IACH,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAUlC;IAED,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiB3D;IAED;;;;;;OAMG;IACH,SAAS,CAAC,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAQvE;IAED,SAAS,CAAC,QAAQ,IAAI,MAAM,CAE3B;IAED,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAErD;CACH;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAGrE"}
|
|
@@ -19,11 +19,13 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
20
|
exports.ConnectionDiagnosticsContribution = void 0;
|
|
21
21
|
exports.bindConnectionDiagnostics = bindConnectionDiagnostics;
|
|
22
|
+
const protocol_1 = require("@hydranium/protocol");
|
|
22
23
|
const core_1 = require("@theia/core");
|
|
23
24
|
const frontend_application_contribution_1 = require("@theia/core/lib/browser/frontend-application-contribution");
|
|
24
25
|
const connection_status_service_1 = require("@theia/core/lib/browser/connection-status-service");
|
|
25
26
|
const ws_connection_source_1 = require("@theia/core/lib/browser/messaging/ws-connection-source");
|
|
26
27
|
const inversify_1 = require("@theia/core/shared/inversify");
|
|
28
|
+
const clock_1 = require("../common/clock");
|
|
27
29
|
const channel_logger_1 = require("./channel-logger");
|
|
28
30
|
const session_aware_connection_source_1 = require("./session-aware-connection-source");
|
|
29
31
|
/**
|
|
@@ -45,10 +47,12 @@ let ConnectionDiagnosticsContribution = class ConnectionDiagnosticsContribution
|
|
|
45
47
|
connectionStatus;
|
|
46
48
|
logger;
|
|
47
49
|
messageService;
|
|
50
|
+
/** Times the outages the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
51
|
+
clock = new protocol_1.SystemClock();
|
|
48
52
|
/** Main channels created so far; more than one means the server did not recognise this frontend. */
|
|
49
53
|
channelCount = 0;
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
sinceSocketClosed;
|
|
55
|
+
sinceOffline;
|
|
52
56
|
initialize() {
|
|
53
57
|
this.connectionSource.onSocketDidOpen(() => this.handleSocketOpen());
|
|
54
58
|
this.connectionSource.onSocketDidClose(() => this.handleSocketClose());
|
|
@@ -62,12 +66,12 @@ let ConnectionDiagnosticsContribution = class ConnectionDiagnosticsContribution
|
|
|
62
66
|
this.logger.debug(`diagnostics active; socket ${this.socketId()}, backend ${this.statusName(this.connectionStatus.currentStatus)}`);
|
|
63
67
|
}
|
|
64
68
|
handleSocketOpen() {
|
|
65
|
-
const downFor = this.
|
|
66
|
-
this.
|
|
69
|
+
const downFor = this.sinceSocketClosed === undefined ? '' : ` after ${Math.round(this.sinceSocketClosed.elapsedMs)} ms down`;
|
|
70
|
+
this.sinceSocketClosed = undefined;
|
|
67
71
|
this.logger.info(`websocket connected: socket ${this.socketId()}${downFor}`);
|
|
68
72
|
}
|
|
69
73
|
handleSocketClose() {
|
|
70
|
-
this.
|
|
74
|
+
this.sinceSocketClosed = this.clock.stopwatch();
|
|
71
75
|
this.logger.info(`websocket disconnected: socket ${this.socketId()}; outgoing messages are buffered until it returns`);
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
@@ -86,12 +90,12 @@ let ConnectionDiagnosticsContribution = class ConnectionDiagnosticsContribution
|
|
|
86
90
|
}
|
|
87
91
|
handleStatusChange(status) {
|
|
88
92
|
if (status === connection_status_service_1.ConnectionStatus.ONLINE) {
|
|
89
|
-
const offlineFor = this.
|
|
90
|
-
this.
|
|
93
|
+
const offlineFor = this.sinceOffline === undefined ? '' : ` after ${Math.round(this.sinceOffline.elapsedMs)} ms`;
|
|
94
|
+
this.sinceOffline = undefined;
|
|
91
95
|
this.logger.info(`backend reachable again${offlineFor}`);
|
|
92
96
|
return;
|
|
93
97
|
}
|
|
94
|
-
this.
|
|
98
|
+
this.sinceOffline = this.clock.stopwatch();
|
|
95
99
|
const socket = this.connectionSource.socket;
|
|
96
100
|
if (socket?.connected) {
|
|
97
101
|
this.logger.warn(`backend stopped answering while socket ${socket.id} is still connected: nothing this session sends will ` +
|
|
@@ -135,6 +139,11 @@ __decorate([
|
|
|
135
139
|
(0, inversify_1.inject)(core_1.MessageService),
|
|
136
140
|
__metadata("design:type", core_1.MessageService)
|
|
137
141
|
], ConnectionDiagnosticsContribution.prototype, "messageService", void 0);
|
|
142
|
+
__decorate([
|
|
143
|
+
(0, inversify_1.inject)(clock_1.Clock),
|
|
144
|
+
(0, inversify_1.optional)(),
|
|
145
|
+
__metadata("design:type", Object)
|
|
146
|
+
], ConnectionDiagnosticsContribution.prototype, "clock", void 0);
|
|
138
147
|
exports.ConnectionDiagnosticsContribution = ConnectionDiagnosticsContribution = __decorate([
|
|
139
148
|
(0, inversify_1.injectable)()
|
|
140
149
|
], ConnectionDiagnosticsContribution);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-diagnostics-contribution.js","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;AAElF,sCAAkD;AAClD,iHAA4G;AAC5G,iGAA8G;AAC9G,iGAAmG;AACnG,
|
|
1
|
+
{"version":3,"file":"connection-diagnostics-contribution.js","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;AAElF,kDAAkE;AAClE,sCAAkD;AAClD,iHAA4G;AAC5G,iGAA8G;AAC9G,iGAAmG;AACnG,4DAA6F;AAC7F,2CAAwC;AAExC,qDAAiD;AACjD,uFAAiF;AAEjF;;;;;;;;;;;;;GAaG;AAEI,IAAM,iCAAiC,GAAvC,MAAM,iCAAiC;IACW,gBAAgB,CAA4B;IAC9C,gBAAgB,CAA0B;IACpD,MAAM,CAAgB;IACrB,cAAc,CAAiB;IAC1E,4FAA4F;IAC9C,KAAK,GAAU,IAAI,sBAAW,EAAE,CAAC;IAE/E,oGAAoG;IAC1F,YAAY,GAAG,CAAC,CAAC;IACjB,iBAAiB,CAAa;IAC9B,YAAY,CAAa;IAEnC,UAAU;QACP,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,IAAI,IAAI,CAAC,gBAAgB,YAAY,8DAA4B,EAAE,CAAC;YACjE,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3F,CAAC;QACD,uFAAuF;QACvF,4EAA4E;QAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,QAAQ,EAAE,aAAa,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACvI,CAAC;IAES,gBAAgB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC;QAC7H,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAChF,CAAC;IAES,iBAAiB;QACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,QAAQ,EAAE,mDAAmD,CAAC,CAAC;IAC1H,CAAC;IAED;;;;OAIG;IACO,iBAAiB;QACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACzE,OAAO;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CACb,gBAAgB,IAAI,CAAC,YAAY,cAAc,IAAI,CAAC,QAAQ,EAAE,iDAAiD;YAC5G,iEAAiE,CACtE,CAAC;IACL,CAAC;IAES,kBAAkB,CAAC,MAAwB;QAClD,IAAI,MAAM,KAAK,4CAAgB,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC;YACjH,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;YACzD,OAAO;QACV,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAC5C,IAAI,MAAM,EAAE,SAAS,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CACb,0CAA0C,MAAM,CAAC,EAAE,uDAAuD;gBACvG,kFAAkF,CACvF,CAAC;YACF,OAAO;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0DAA0D,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAClG,CAAC;IAED;;;;;;OAMG;IACO,oBAAoB,CAAC,QAAkC;QAC9D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,QAAQ,CAAC,QAAQ,kBAAkB,QAAQ,CAAC,QAAQ,aAAa,CAAC,CAAC;QACvG,IAAI,CAAC,cAAc,CAAC,KAAK,CACtB,UAAG,CAAC,QAAQ,CACT,0CAA0C,EAC1C,6FAA6F,CAC/F,CACH,CAAC;IACL,CAAC;IAES,QAAQ;QACf,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,IAAI,gDAAyB,CAAC,aAAa,CAAC;IACtF,CAAC;IAES,UAAU,CAAC,MAAwB;QAC1C,OAAO,MAAM,KAAK,4CAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC;CACH,CAAA;;AAhGwD;IAArD,IAAA,kBAAM,EAAC,gDAAyB,CAAC;8BAAsC,gDAAyB;2EAAC;AAC9C;IAAnD,IAAA,kBAAM,EAAC,mDAAuB,CAAC;;2EAA8D;AACpD;IAAzC,IAAA,kBAAM,EAAC,8BAAa,CAAC;8BAA4B,8BAAa;iEAAC;AACrB;IAA1C,IAAA,kBAAM,EAAC,qBAAc,CAAC;8BAAoC,qBAAc;yEAAC;AAE5B;IAA7C,IAAA,kBAAM,EAAC,aAAK,CAAC;IAAE,IAAA,oBAAQ,GAAE;;gEAAqD;4CANrE,iCAAiC;IAD7C,IAAA,sBAAU,GAAE;GACA,iCAAiC,CAiG7C;AAED;;;;;;;GAOG;AACH,mCAA0C,IAAqB;IAC5D,IAAI,CAAC,iCAAiC,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACpE,IAAI,CAAC,mEAA+B,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
+
import { type Stopwatch } from '@hydranium/protocol';
|
|
9
10
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
10
11
|
import { AbstractChannel } from '@theia/core/lib/common/message-rpc/channel';
|
|
11
12
|
import { type WriteBuffer } from '@theia/core/lib/common/message-rpc/message-buffer';
|
|
12
13
|
import { WebsocketFrontendConnectionService } from '@theia/core/lib/node/messaging/websocket-frontend-connection-service';
|
|
13
14
|
import { type interfaces } from '@theia/core/shared/inversify';
|
|
15
|
+
import { Clock } from '../common/clock';
|
|
14
16
|
import { type ConnectionResilienceOptions } from '../common/connection-resilience-options';
|
|
15
17
|
import { FramedSocketWriteBuffer } from '../common/framed-socket-write-buffer';
|
|
16
18
|
import { InboundMessageSequence } from '../common/inbound-message-sequence';
|
|
@@ -74,13 +76,15 @@ export declare class AcknowledgedSocketChannel extends AbstractChannel {
|
|
|
74
76
|
* not a changed body, so this copy can go stale in silence.
|
|
75
77
|
*/
|
|
76
78
|
export declare class SessionBoundFrontendConnectionService extends WebsocketFrontendConnectionService {
|
|
77
|
-
/**
|
|
79
|
+
/** Times the gaps the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
80
|
+
protected readonly clock: Clock;
|
|
81
|
+
/** Socket each frontend's channel is currently bound to, with how long it has been. */
|
|
78
82
|
protected readonly bindings: Map<string, {
|
|
79
83
|
socketId: string;
|
|
80
|
-
|
|
84
|
+
sinceBound: Stopwatch;
|
|
81
85
|
}>;
|
|
82
|
-
/**
|
|
83
|
-
protected readonly
|
|
86
|
+
/** Running since a frontend's live socket went away, so the reconnect gap can be reported. */
|
|
87
|
+
protected readonly sinceOffline: Map<string, Stopwatch>;
|
|
84
88
|
handleSocketDisconnect(socket: FrontendSocket, channel: FrontendChannel, frontEndId: string): void;
|
|
85
89
|
/**
|
|
86
90
|
* Theia's body, building an {@link AcknowledgedSocketChannel} in place of its own channel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-bound-frontend-connection-service.d.ts","sourceRoot":"","sources":["../../src/node/session-bound-frontend-connection-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAc,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mDAAmD,CAAC;AAIrF,OAAO,EAAE,kCAAkC,EAAE,MAAM,sEAAsE,CAAC;AAC1H,OAAO,
|
|
1
|
+
{"version":3,"file":"session-bound-frontend-connection-service.d.ts","sourceRoot":"","sources":["../../src/node/session-bound-frontend-connection-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAc,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mDAAmD,CAAC;AAIrF,OAAO,EAAE,kCAAkC,EAAE,MAAM,sEAAsE,CAAC;AAC1H,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAGJ,uBAAuB,EAGzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAyB,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAEnG;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,kCAAkC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzG;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,kCAAkC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1G;;;;;;;;;;GAUG;AACH,qBAAa,yBAA0B,SAAQ,eAAe;IAK/C,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,uBAAuB;IAJpE,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,iBAAiB,uBAA8B;IACzD,SAAS,CAAC,QAAQ,CAAC,OAAO,yBAA8F;IAExH,YAA+B,YAAY,EAAE,uBAAuB,EAInE;IAED,oGAAoG;IACpG,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA+BpC;IAED,UAAU,IAAI,IAAI,CAGjB;IAED,WAAW,IAAI,IAAI,CAElB;IAED,cAAc,IAAI,WAAW,CAI5B;CACH;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,qCAAsC,SAAQ,kCAAkC;IAC1F,yFAAyF;IAC9D,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAqB;IAC/E,uFAAuF;IACvF,SAAS,CAAC,QAAQ,CAAC,QAAQ;kBAA+B,MAAM;oBAAc,SAAS;OAAM;IAC7F,8FAA8F;IAC9F,SAAS,CAAC,QAAQ,CAAC,YAAY,yBAAgC;IAEtD,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAwC1G;IAED;;;;;;OAMG;IACH,UAAmB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CAK/F;IAED;;;OAGG;IACH,SAAS,CAAC,iBAAiB,IAAI,uBAAuB,CAOrD;IAED,UAAmB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK3E;IAED;mFAC+E;IAC/E,SAAS,CAAC,iBAAiB,IAAI,MAAM,CAMpC;CACH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CACrC,IAAI,EAAE,UAAU,CAAC,IAAI,EACrB,OAAO,EAAE,UAAU,CAAC,OAAO,EAC3B,MAAM,EAAE,UAAU,CAAC,MAAM,EACzB,OAAO,GAAE,2BAAgC,GACzC,OAAO,CAST"}
|
|
@@ -13,9 +13,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
13
13
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
14
14
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
15
|
};
|
|
16
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
17
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
18
|
+
};
|
|
16
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
20
|
exports.SessionBoundFrontendConnectionService = exports.AcknowledgedSocketChannel = void 0;
|
|
18
21
|
exports.bindConnectionResilience = bindConnectionResilience;
|
|
22
|
+
const protocol_1 = require("@hydranium/protocol");
|
|
19
23
|
const disposable_1 = require("@theia/core/lib/common/disposable");
|
|
20
24
|
const channel_1 = require("@theia/core/lib/common/message-rpc/channel");
|
|
21
25
|
const uint8_array_message_buffer_1 = require("@theia/core/lib/common/message-rpc/uint8-array-message-buffer");
|
|
@@ -23,6 +27,7 @@ const backend_application_config_provider_1 = require("@theia/core/lib/node/back
|
|
|
23
27
|
const socket_write_buffer_1 = require("@theia/core/lib/common/messaging/socket-write-buffer");
|
|
24
28
|
const websocket_frontend_connection_service_1 = require("@theia/core/lib/node/messaging/websocket-frontend-connection-service");
|
|
25
29
|
const inversify_1 = require("@theia/core/shared/inversify");
|
|
30
|
+
const clock_1 = require("../common/clock");
|
|
26
31
|
const framed_socket_write_buffer_1 = require("../common/framed-socket-write-buffer");
|
|
27
32
|
const inbound_message_sequence_1 = require("../common/inbound-message-sequence");
|
|
28
33
|
/**
|
|
@@ -112,17 +117,19 @@ exports.AcknowledgedSocketChannel = AcknowledgedSocketChannel;
|
|
|
112
117
|
* not a changed body, so this copy can go stale in silence.
|
|
113
118
|
*/
|
|
114
119
|
let SessionBoundFrontendConnectionService = class SessionBoundFrontendConnectionService extends websocket_frontend_connection_service_1.WebsocketFrontendConnectionService {
|
|
115
|
-
/**
|
|
120
|
+
/** Times the gaps the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
121
|
+
clock = new protocol_1.SystemClock();
|
|
122
|
+
/** Socket each frontend's channel is currently bound to, with how long it has been. */
|
|
116
123
|
bindings = new Map();
|
|
117
|
-
/**
|
|
118
|
-
|
|
124
|
+
/** Running since a frontend's live socket went away, so the reconnect gap can be reported. */
|
|
125
|
+
sinceOffline = new Map();
|
|
119
126
|
handleSocketDisconnect(socket, channel, frontEndId) {
|
|
120
127
|
const previous = this.bindings.get(frontEndId);
|
|
121
|
-
this.bindings.set(frontEndId, { socketId: socket.id,
|
|
122
|
-
const
|
|
123
|
-
this.
|
|
128
|
+
this.bindings.set(frontEndId, { socketId: socket.id, sinceBound: this.clock.stopwatch() });
|
|
129
|
+
const sinceOffline = this.sinceOffline.get(frontEndId);
|
|
130
|
+
this.sinceOffline.delete(frontEndId);
|
|
124
131
|
const replacing = previous ? `, replacing socket ${previous.socketId}` : '';
|
|
125
|
-
const gap =
|
|
132
|
+
const gap = sinceOffline === undefined ? '' : `, after ${Math.round(sinceOffline.elapsedMs)} ms offline`;
|
|
126
133
|
console.info(`${framed_socket_write_buffer_1.CONNECTION_LOG_PREFIX} frontend ${frontEndId} channel bound to socket ${socket.id}${replacing}${gap}`);
|
|
127
134
|
socket.on('disconnect', reason => {
|
|
128
135
|
const bound = this.bindings.get(frontEndId);
|
|
@@ -131,13 +138,13 @@ let SessionBoundFrontendConnectionService = class SessionBoundFrontendConnection
|
|
|
131
138
|
// deletes the binding. Neither owns the channel, so neither may disconnect it, arm a close
|
|
132
139
|
// timeout, or close a connection that is no longer in `connectionsByFrontend`.
|
|
133
140
|
const owner = bound
|
|
134
|
-
? `socket ${bound.socketId} owns it (bound ${
|
|
141
|
+
? `socket ${bound.socketId} owns it (bound ${Math.round(bound.sinceBound.elapsedMs)} ms ago)`
|
|
135
142
|
: 'the connection is already closed';
|
|
136
143
|
console.info(`${framed_socket_write_buffer_1.CONNECTION_LOG_PREFIX} ignoring disconnect of stale socket ${socket.id} (frontend ${frontEndId}, ${reason}); ${owner}`);
|
|
137
144
|
return;
|
|
138
145
|
}
|
|
139
146
|
// From here on: Theia's own handler body, unchanged apart from naming the socket.
|
|
140
|
-
this.
|
|
147
|
+
this.sinceOffline.set(frontEndId, this.clock.stopwatch());
|
|
141
148
|
console.info(`${framed_socket_write_buffer_1.CONNECTION_LOG_PREFIX} socket ${socket.id} (frontend ${frontEndId}) disconnected: ${reason}`);
|
|
142
149
|
channel.disconnect();
|
|
143
150
|
const timeout = this.connectionTimeout();
|
|
@@ -180,7 +187,7 @@ let SessionBoundFrontendConnectionService = class SessionBoundFrontendConnection
|
|
|
180
187
|
closeConnection(frontEndId, reason) {
|
|
181
188
|
console.info(`${framed_socket_write_buffer_1.CONNECTION_LOG_PREFIX} closing frontend ${frontEndId}: ${reason}`);
|
|
182
189
|
this.bindings.delete(frontEndId);
|
|
183
|
-
this.
|
|
190
|
+
this.sinceOffline.delete(frontEndId);
|
|
184
191
|
super.closeConnection(frontEndId, reason);
|
|
185
192
|
}
|
|
186
193
|
/** Mirrors Theia's private `frontendConnectionTimeout`, including `Number('')` resolving to 0.
|
|
@@ -194,6 +201,11 @@ let SessionBoundFrontendConnectionService = class SessionBoundFrontendConnection
|
|
|
194
201
|
}
|
|
195
202
|
};
|
|
196
203
|
exports.SessionBoundFrontendConnectionService = SessionBoundFrontendConnectionService;
|
|
204
|
+
__decorate([
|
|
205
|
+
(0, inversify_1.inject)(clock_1.Clock),
|
|
206
|
+
(0, inversify_1.optional)(),
|
|
207
|
+
__metadata("design:type", Object)
|
|
208
|
+
], SessionBoundFrontendConnectionService.prototype, "clock", void 0);
|
|
197
209
|
exports.SessionBoundFrontendConnectionService = SessionBoundFrontendConnectionService = __decorate([
|
|
198
210
|
(0, inversify_1.injectable)()
|
|
199
211
|
], SessionBoundFrontendConnectionService);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-bound-frontend-connection-service.js","sourceRoot":"","sources":["../../src/node/session-bound-frontend-connection-service.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF
|
|
1
|
+
{"version":3,"file":"session-bound-frontend-connection-service.js","sourceRoot":"","sources":["../../src/node/session-bound-frontend-connection-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydranium/client-theia",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.271",
|
|
4
4
|
"description": "Cross-head Theia client primitives shared by the hydranium protocol heads. Provides the socket-forwarding connection-handler base that the data-server and GLSP Theia integrations subclass, plus the preference-driven Output-channel logger; carries no head-specific dependency.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hydranium",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"watch": "tsc -b -w --preserveWatchOutput"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
68
|
+
"@hydranium/protocol": "1.0.0-next.271",
|
|
69
69
|
"@theia/core": "^1.70.0",
|
|
70
70
|
"@theia/editor": "^1.70.0",
|
|
71
71
|
"@theia/filesystem": "^1.70.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"vscode-jsonrpc": "9.0.0"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
81
|
+
"@hydranium/protocol": "1.0.0-next.271",
|
|
82
82
|
"@theia/core": "^1.70.0",
|
|
83
83
|
"@theia/editor": "^1.70.0",
|
|
84
84
|
"@theia/filesystem": "^1.70.0",
|
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
+
import { type Stopwatch, SystemClock } from '@hydranium/protocol';
|
|
10
11
|
import { MessageService, nls } from '@theia/core';
|
|
11
12
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application-contribution';
|
|
12
13
|
import { ConnectionStatus, ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';
|
|
13
14
|
import { WebSocketConnectionSource } from '@theia/core/lib/browser/messaging/ws-connection-source';
|
|
14
|
-
import { inject, injectable, type interfaces } from '@theia/core/shared/inversify';
|
|
15
|
+
import { inject, injectable, optional, type interfaces } from '@theia/core/shared/inversify';
|
|
16
|
+
import { Clock } from '../common/clock';
|
|
15
17
|
import { type ConnectionBufferOverflow } from '../common/framed-socket-write-buffer';
|
|
16
18
|
import { ChannelLogger } from './channel-logger';
|
|
17
19
|
import { SessionAwareConnectionSource } from './session-aware-connection-source';
|
|
@@ -36,11 +38,13 @@ export class ConnectionDiagnosticsContribution implements FrontendApplicationCon
|
|
|
36
38
|
@inject(ConnectionStatusService) protected readonly connectionStatus: ConnectionStatusService;
|
|
37
39
|
@inject(ChannelLogger) protected readonly logger: ChannelLogger;
|
|
38
40
|
@inject(MessageService) protected readonly messageService: MessageService;
|
|
41
|
+
/** Times the outages the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
42
|
+
@inject(Clock) @optional() protected readonly clock: Clock = new SystemClock();
|
|
39
43
|
|
|
40
44
|
/** Main channels created so far; more than one means the server did not recognise this frontend. */
|
|
41
45
|
protected channelCount = 0;
|
|
42
|
-
protected
|
|
43
|
-
protected
|
|
46
|
+
protected sinceSocketClosed?: Stopwatch;
|
|
47
|
+
protected sinceOffline?: Stopwatch;
|
|
44
48
|
|
|
45
49
|
initialize(): void {
|
|
46
50
|
this.connectionSource.onSocketDidOpen(() => this.handleSocketOpen());
|
|
@@ -56,13 +60,13 @@ export class ConnectionDiagnosticsContribution implements FrontendApplicationCon
|
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
protected handleSocketOpen(): void {
|
|
59
|
-
const downFor = this.
|
|
60
|
-
this.
|
|
63
|
+
const downFor = this.sinceSocketClosed === undefined ? '' : ` after ${Math.round(this.sinceSocketClosed.elapsedMs)} ms down`;
|
|
64
|
+
this.sinceSocketClosed = undefined;
|
|
61
65
|
this.logger.info(`websocket connected: socket ${this.socketId()}${downFor}`);
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
protected handleSocketClose(): void {
|
|
65
|
-
this.
|
|
69
|
+
this.sinceSocketClosed = this.clock.stopwatch();
|
|
66
70
|
this.logger.info(`websocket disconnected: socket ${this.socketId()}; outgoing messages are buffered until it returns`);
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -85,12 +89,12 @@ export class ConnectionDiagnosticsContribution implements FrontendApplicationCon
|
|
|
85
89
|
|
|
86
90
|
protected handleStatusChange(status: ConnectionStatus): void {
|
|
87
91
|
if (status === ConnectionStatus.ONLINE) {
|
|
88
|
-
const offlineFor = this.
|
|
89
|
-
this.
|
|
92
|
+
const offlineFor = this.sinceOffline === undefined ? '' : ` after ${Math.round(this.sinceOffline.elapsedMs)} ms`;
|
|
93
|
+
this.sinceOffline = undefined;
|
|
90
94
|
this.logger.info(`backend reachable again${offlineFor}`);
|
|
91
95
|
return;
|
|
92
96
|
}
|
|
93
|
-
this.
|
|
97
|
+
this.sinceOffline = this.clock.stopwatch();
|
|
94
98
|
const socket = this.connectionSource.socket;
|
|
95
99
|
if (socket?.connected) {
|
|
96
100
|
this.logger.warn(
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
+
import { type Stopwatch, SystemClock } from '@hydranium/protocol';
|
|
10
11
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
11
12
|
import { AbstractChannel } from '@theia/core/lib/common/message-rpc/channel';
|
|
12
13
|
import { type WriteBuffer } from '@theia/core/lib/common/message-rpc/message-buffer';
|
|
@@ -14,7 +15,8 @@ import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '@theia/core/lib/com
|
|
|
14
15
|
import { BackendApplicationConfigProvider } from '@theia/core/lib/node/backend-application-config-provider';
|
|
15
16
|
import { SocketWriteBuffer } from '@theia/core/lib/common/messaging/socket-write-buffer';
|
|
16
17
|
import { WebsocketFrontendConnectionService } from '@theia/core/lib/node/messaging/websocket-frontend-connection-service';
|
|
17
|
-
import { injectable, type interfaces } from '@theia/core/shared/inversify';
|
|
18
|
+
import { inject, injectable, optional, type interfaces } from '@theia/core/shared/inversify';
|
|
19
|
+
import { Clock } from '../common/clock';
|
|
18
20
|
import { type ConnectionResilienceOptions } from '../common/connection-resilience-options';
|
|
19
21
|
import {
|
|
20
22
|
CONNECTION_LOG_PREFIX as PREFIX,
|
|
@@ -137,19 +139,21 @@ export class AcknowledgedSocketChannel extends AbstractChannel {
|
|
|
137
139
|
*/
|
|
138
140
|
@injectable()
|
|
139
141
|
export class SessionBoundFrontendConnectionService extends WebsocketFrontendConnectionService {
|
|
140
|
-
/**
|
|
141
|
-
protected readonly
|
|
142
|
-
/**
|
|
143
|
-
protected readonly
|
|
142
|
+
/** Times the gaps the log reports: the container's {@link Clock}, or a `SystemClock`. */
|
|
143
|
+
@inject(Clock) @optional() protected readonly clock: Clock = new SystemClock();
|
|
144
|
+
/** Socket each frontend's channel is currently bound to, with how long it has been. */
|
|
145
|
+
protected readonly bindings = new Map<string, { socketId: string; sinceBound: Stopwatch }>();
|
|
146
|
+
/** Running since a frontend's live socket went away, so the reconnect gap can be reported. */
|
|
147
|
+
protected readonly sinceOffline = new Map<string, Stopwatch>();
|
|
144
148
|
|
|
145
149
|
override handleSocketDisconnect(socket: FrontendSocket, channel: FrontendChannel, frontEndId: string): void {
|
|
146
150
|
const previous = this.bindings.get(frontEndId);
|
|
147
|
-
this.bindings.set(frontEndId, { socketId: socket.id,
|
|
151
|
+
this.bindings.set(frontEndId, { socketId: socket.id, sinceBound: this.clock.stopwatch() });
|
|
148
152
|
|
|
149
|
-
const
|
|
150
|
-
this.
|
|
153
|
+
const sinceOffline = this.sinceOffline.get(frontEndId);
|
|
154
|
+
this.sinceOffline.delete(frontEndId);
|
|
151
155
|
const replacing = previous ? `, replacing socket ${previous.socketId}` : '';
|
|
152
|
-
const gap =
|
|
156
|
+
const gap = sinceOffline === undefined ? '' : `, after ${Math.round(sinceOffline.elapsedMs)} ms offline`;
|
|
153
157
|
console.info(`${PREFIX} frontend ${frontEndId} channel bound to socket ${socket.id}${replacing}${gap}`);
|
|
154
158
|
|
|
155
159
|
socket.on('disconnect', reason => {
|
|
@@ -159,14 +163,14 @@ export class SessionBoundFrontendConnectionService extends WebsocketFrontendConn
|
|
|
159
163
|
// deletes the binding. Neither owns the channel, so neither may disconnect it, arm a close
|
|
160
164
|
// timeout, or close a connection that is no longer in `connectionsByFrontend`.
|
|
161
165
|
const owner = bound
|
|
162
|
-
? `socket ${bound.socketId} owns it (bound ${
|
|
166
|
+
? `socket ${bound.socketId} owns it (bound ${Math.round(bound.sinceBound.elapsedMs)} ms ago)`
|
|
163
167
|
: 'the connection is already closed';
|
|
164
168
|
console.info(`${PREFIX} ignoring disconnect of stale socket ${socket.id} (frontend ${frontEndId}, ${reason}); ${owner}`);
|
|
165
169
|
return;
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
// From here on: Theia's own handler body, unchanged apart from naming the socket.
|
|
169
|
-
this.
|
|
173
|
+
this.sinceOffline.set(frontEndId, this.clock.stopwatch());
|
|
170
174
|
console.info(`${PREFIX} socket ${socket.id} (frontend ${frontEndId}) disconnected: ${reason}`);
|
|
171
175
|
channel.disconnect();
|
|
172
176
|
const timeout = this.connectionTimeout();
|
|
@@ -214,7 +218,7 @@ export class SessionBoundFrontendConnectionService extends WebsocketFrontendConn
|
|
|
214
218
|
protected override closeConnection(frontEndId: string, reason: string): void {
|
|
215
219
|
console.info(`${PREFIX} closing frontend ${frontEndId}: ${reason}`);
|
|
216
220
|
this.bindings.delete(frontEndId);
|
|
217
|
-
this.
|
|
221
|
+
this.sinceOffline.delete(frontEndId);
|
|
218
222
|
super.closeConnection(frontEndId, reason);
|
|
219
223
|
}
|
|
220
224
|
|