UNPKG

8.65 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2018 TypeFox and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16// *****************************************************************************
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.ApplicationConnectionStatusContribution = exports.FrontendConnectionStatusService = exports.AbstractConnectionStatusService = exports.PingService = exports.ConnectionStatusOptions = exports.ConnectionStatus = exports.ConnectionStatusService = void 0;
19const tslib_1 = require("tslib");
20const inversify_1 = require("inversify");
21const logger_1 = require("../common/logger");
22const event_1 = require("../common/event");
23const frontend_application_contribution_1 = require("./frontend-application-contribution");
24const status_bar_1 = require("./status-bar/status-bar");
25const common_1 = require("../common");
26const ws_connection_source_1 = require("./messaging/ws-connection-source");
27/**
28 * Service for listening on backend connection changes.
29 */
30exports.ConnectionStatusService = Symbol('ConnectionStatusService');
31/**
32 * The connection status.
33 */
34var ConnectionStatus;
35(function (ConnectionStatus) {
36 /**
37 * Connected to the backend.
38 */
39 ConnectionStatus[ConnectionStatus["ONLINE"] = 0] = "ONLINE";
40 /**
41 * The connection is lost between frontend and backend.
42 */
43 ConnectionStatus[ConnectionStatus["OFFLINE"] = 1] = "OFFLINE";
44})(ConnectionStatus = exports.ConnectionStatus || (exports.ConnectionStatus = {}));
45let ConnectionStatusOptions = class ConnectionStatusOptions {
46};
47ConnectionStatusOptions.DEFAULT = {
48 offlineTimeout: 5000,
49};
50ConnectionStatusOptions = (0, tslib_1.__decorate)([
51 (0, inversify_1.injectable)()
52], ConnectionStatusOptions);
53exports.ConnectionStatusOptions = ConnectionStatusOptions;
54exports.PingService = Symbol('PingService');
55let AbstractConnectionStatusService = class AbstractConnectionStatusService {
56 constructor(options = ConnectionStatusOptions.DEFAULT) {
57 this.options = options;
58 this.statusChangeEmitter = new event_1.Emitter();
59 this.connectionStatus = ConnectionStatus.ONLINE;
60 }
61 get onStatusChange() {
62 return this.statusChangeEmitter.event;
63 }
64 get currentStatus() {
65 return this.connectionStatus;
66 }
67 dispose() {
68 this.statusChangeEmitter.dispose();
69 }
70 updateStatus(success) {
71 const previousStatus = this.connectionStatus;
72 const newStatus = success ? ConnectionStatus.ONLINE : ConnectionStatus.OFFLINE;
73 if (previousStatus !== newStatus) {
74 this.connectionStatus = newStatus;
75 this.fireStatusChange(newStatus);
76 }
77 }
78 fireStatusChange(status) {
79 this.statusChangeEmitter.fire(status);
80 }
81};
82(0, tslib_1.__decorate)([
83 (0, inversify_1.inject)(logger_1.ILogger),
84 (0, tslib_1.__metadata)("design:type", Object)
85], AbstractConnectionStatusService.prototype, "logger", void 0);
86AbstractConnectionStatusService = (0, tslib_1.__decorate)([
87 (0, inversify_1.injectable)(),
88 (0, tslib_1.__param)(0, (0, inversify_1.inject)(ConnectionStatusOptions)),
89 (0, tslib_1.__param)(0, (0, inversify_1.optional)()),
90 (0, tslib_1.__metadata)("design:paramtypes", [ConnectionStatusOptions])
91], AbstractConnectionStatusService);
92exports.AbstractConnectionStatusService = AbstractConnectionStatusService;
93let FrontendConnectionStatusService = class FrontendConnectionStatusService extends AbstractConnectionStatusService {
94 init() {
95 this.wsConnectionProvider.onSocketDidOpen(() => {
96 this.updateStatus(true);
97 this.schedulePing();
98 });
99 this.wsConnectionProvider.onSocketDidClose(() => {
100 this.clearTimeout(this.scheduledPing);
101 this.updateStatus(false);
102 });
103 this.wsConnectionProvider.onIncomingMessageActivity(() => {
104 // natural activity
105 this.updateStatus(true);
106 this.schedulePing();
107 });
108 }
109 schedulePing() {
110 this.clearTimeout(this.scheduledPing);
111 this.scheduledPing = this.setTimeout(async () => {
112 await this.performPingRequest();
113 this.schedulePing();
114 }, this.options.offlineTimeout);
115 }
116 async performPingRequest() {
117 try {
118 await this.pingService.ping();
119 this.updateStatus(true);
120 }
121 catch (e) {
122 this.updateStatus(false);
123 await this.logger.error(e);
124 }
125 }
126 // eslint-disable-next-line @typescript-eslint/no-explicit-any
127 setTimeout(handler, timeout) {
128 return window.setTimeout(handler, timeout);
129 }
130 clearTimeout(handle) {
131 if (handle !== undefined) {
132 window.clearTimeout(handle);
133 }
134 }
135};
136(0, tslib_1.__decorate)([
137 (0, inversify_1.inject)(ws_connection_source_1.WebSocketConnectionSource),
138 (0, tslib_1.__metadata)("design:type", ws_connection_source_1.WebSocketConnectionSource)
139], FrontendConnectionStatusService.prototype, "wsConnectionProvider", void 0);
140(0, tslib_1.__decorate)([
141 (0, inversify_1.inject)(exports.PingService),
142 (0, tslib_1.__metadata)("design:type", Object)
143], FrontendConnectionStatusService.prototype, "pingService", void 0);
144(0, tslib_1.__decorate)([
145 (0, inversify_1.postConstruct)(),
146 (0, tslib_1.__metadata)("design:type", Function),
147 (0, tslib_1.__metadata)("design:paramtypes", []),
148 (0, tslib_1.__metadata)("design:returntype", void 0)
149], FrontendConnectionStatusService.prototype, "init", null);
150FrontendConnectionStatusService = (0, tslib_1.__decorate)([
151 (0, inversify_1.injectable)()
152], FrontendConnectionStatusService);
153exports.FrontendConnectionStatusService = FrontendConnectionStatusService;
154let ApplicationConnectionStatusContribution = class ApplicationConnectionStatusContribution extends frontend_application_contribution_1.DefaultFrontendApplicationContribution {
155 constructor(connectionStatusService, statusBar, logger) {
156 super();
157 this.connectionStatusService = connectionStatusService;
158 this.statusBar = statusBar;
159 this.logger = logger;
160 this.toDisposeOnOnline = new common_1.DisposableCollection();
161 this.statusbarId = 'connection-status';
162 this.connectionStatusService.onStatusChange(state => this.onStateChange(state));
163 }
164 onStateChange(state) {
165 switch (state) {
166 case ConnectionStatus.OFFLINE: {
167 this.handleOffline();
168 break;
169 }
170 case ConnectionStatus.ONLINE: {
171 this.handleOnline();
172 break;
173 }
174 }
175 }
176 handleOnline() {
177 this.toDisposeOnOnline.dispose();
178 }
179 handleOffline() {
180 this.statusBar.setElement(this.statusbarId, {
181 alignment: status_bar_1.StatusBarAlignment.LEFT,
182 text: common_1.nls.localize('theia/core/offline', 'Offline'),
183 tooltip: common_1.nls.localize('theia/localize/offlineTooltip', 'Cannot connect to backend.'),
184 priority: 5000
185 });
186 this.toDisposeOnOnline.push(common_1.Disposable.create(() => this.statusBar.removeElement(this.statusbarId)));
187 document.body.classList.add('theia-mod-offline');
188 this.toDisposeOnOnline.push(common_1.Disposable.create(() => document.body.classList.remove('theia-mod-offline')));
189 }
190};
191ApplicationConnectionStatusContribution = (0, tslib_1.__decorate)([
192 (0, inversify_1.injectable)(),
193 (0, tslib_1.__param)(0, (0, inversify_1.inject)(exports.ConnectionStatusService)),
194 (0, tslib_1.__param)(1, (0, inversify_1.inject)(status_bar_1.StatusBar)),
195 (0, tslib_1.__param)(2, (0, inversify_1.inject)(logger_1.ILogger)),
196 (0, tslib_1.__metadata)("design:paramtypes", [Object, Object, Object])
197], ApplicationConnectionStatusContribution);
198exports.ApplicationConnectionStatusContribution = ApplicationConnectionStatusContribution;
199//# sourceMappingURL=connection-status-service.js.map
\No newline at end of file