Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve transition to/from "offline" state #12196

Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@theia/filesystem": "1.34.0",
"@theia/getting-started": "1.34.0",
"@theia/git": "1.34.0",
"@theia/hang-backend": "1.34.0",
"@theia/keymaps": "1.34.0",
"@theia/markers": "1.34.0",
"@theia/memory-inspector": "1.34.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/browser/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
{
"path": "../../packages/git"
},
{
"path": "../../packages/hang-backend"
},
{
"path": "../../packages/keymaps"
},
Expand Down
1 change: 1 addition & 0 deletions examples/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@theia/filesystem": "1.34.0",
"@theia/getting-started": "1.34.0",
"@theia/git": "1.34.0",
"@theia/hang-backend": "1.34.0",
"@theia/keymaps": "1.34.0",
"@theia/markers": "1.34.0",
"@theia/memory-inspector": "1.34.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/electron/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
{
"path": "../../packages/git"
},
{
"path": "../../packages/hang-backend"
},
{
"path": "../../packages/keymaps"
},
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/browser/connection-status-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ export class FrontendConnectionStatusService extends AbstractConnectionStatusSer

protected async performPingRequest(): Promise<void> {
try {
await this.pingService.ping();
const success = this.pingService.ping();
const failure = new Promise((_, reject) => setTimeout(reject, this.options.offlineTimeout * 2));
await Promise.race([success, failure]);
this.updateStatus(true);
} catch (e) {
this.updateStatus(false);
Expand Down
10 changes: 10 additions & 0 deletions packages/hang-backend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: [
'../../configs/build.eslintrc.json'
],
parserOptions: {
tsconfigRootDir: __dirname,
project: 'tsconfig.json'
}
};
71 changes: 71 additions & 0 deletions packages/hang-backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<div align='center'>

<br />

<img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />

<h2>ECLIPSE THEIA - MEMORY-INSPECTOR EXTENSION</h2>

<hr />

</div>

## Description

This extension contributes a set of widgets for viewing memory in different ways.

## Requirements

This extension must be used in conjunction with a Debug Adapter that implements a `ReadMemoryRequest` handler or alternative custom request that returns memory data.
It has been tested against the [CDT-GDB Adapter](https://github.com/eclipse-cdt/cdt-gdb-adapter) used as the backend for the
[CDT-GDB VSCode](https://github.com/eclipse-cdt/cdt-gdb-vscode) plugin. This repository is configured to download that plugin as part of its build routine.
If you intend to use this extension with a different debug adapter, you may need to implement a custom
[`MemoryProvider`](./src/browser/memory-provider/memory-provider-service.ts) to handle any peculiarities of the requests and responses used by your adapter.

## Widgets

### Memory Widget

The basic [`MemoryWidget` class](./src/browser/memory-widget/memory-widget.ts) is a wrapper around two functional widgets, a `MemoryOptionsWidget` and
a`MemoryTableWidget`. The [`MemoryOptionsWidget`](./src/browser/memory-widget/memory-options-widget.tsx) is responsible for configuring the display
and fetching memory, and the [`MemoryTableWidget`](./src/browser/memory-widget/memory-table-widget.tsx) renders the memory according to the options
specified by the user in the `MemoryOptionsWidget`. The basic combination of these three classes offers variable highlighting, ascii display, and
dynamic updating in response to events from the debug session, as well as the option to lock the view to ignore changes from the session.

### Diff Widget

The [`MemoryDiffWidget`](./src/browser/diff-widget/memory-diff-widget-types.ts) is an elaboration of the `MemoryWidget` type that allows side-by-side
comparison of the contents of two `MemoryWidgets`.

### Register Widget

The [`RegisterWidget`](./src/browser/register-widget/register-widget-types.ts) offers functionality to view and
manipulate those values when using a debug adapter that reports register contents.

### Editable Widget

The [`MemoryEditableTableWidget`](./src/browser/editable-widget/memory-editable-table-widget.tsx) adds UI functionality to allow users to modify values in
the table display and send them to a backend that supports that operation.

## Using the Widgets

The widgets are created by the [`MemoryWidgetManager`](./src/browser/utils/memory-widget-manager.ts), and modifying the `createNewMemoryWidget()`
method of that service allows you to change what kind of widget is instantiated and under what circumstances. The widgets get memory through the
[`MemoryProviderService`](./src/browser/memory-provider/memory-provider-service.ts), which delegates to implementations `MemoryProvider` interface
that are bound as `MemoryProvider` contributions.


## Additional Information

- [API documentation for `@theia/getting-started`](https://eclipse-theia.github.io/theia/docs/next/modules/getting_started.html)
- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark
"Theia" is a trademark of the Eclipse Foundation
https://www.eclipse.org/theia
44 changes: 44 additions & 0 deletions packages/hang-backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@theia/hang-backend",
"version": "1.34.0",
"description": "Theia - Hang Backend",
"keywords": [
"theia-extension"
],
"homepage": "https://github.com/eclipse-theia/theia",
"license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0",
"repository": {
"type": "git",
"url": "https://github.com/eclipse-theia/theia.git"
},
"bugs": {
"url": "https://github.com/eclipse-theia/theia/issues"
},
"files": [
"lib",
"src"
],
"scripts": {
"build": "theiaext build",
"clean": "theiaext clean",
"compile": "theiaext compile",
"lint": "theiaext lint",
"test": "theiaext test",
"watch": "theiaext watch"
},
"dependencies": {
"@theia/core": "1.34.0"
},
"devDependencies": {
"@types/long": "^4.0.0"
},
"theiaExtensions": [
{
"frontend": "lib/browser/hang-backend-frontend-module",
"backend": "lib/node/hang-backend-backend-module"
}
],
"publishConfig": {
"access": "public"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/********************************************************************************
* Copyright (C) 2023 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { inject, injectable } from '@theia/core/shared/inversify';
import { CommandContribution, CommandRegistry } from '@theia/core/lib/common/command';
import { HangBackendService } from '../common/types';

@injectable()
export class HangBackendCommandContribution implements CommandContribution {
@inject(HangBackendService) protected readonly hangBackendService: HangBackendService;

registerCommands(commands: CommandRegistry): void {
commands.registerCommand({ id: 'hangBackend', label: 'Hang Backend' }, {
execute: () => this.hangBackendService.hangBackend(30_000),
});
}
}
32 changes: 32 additions & 0 deletions packages/hang-backend/src/browser/hang-backend-frontend-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (C) 2023 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { ContainerModule } from '@theia/core/shared/inversify';
import { CommandContribution } from '@theia/core/lib/common/command';
import { WebSocketConnectionProvider } from '@theia/core/lib/browser';
import { HangBackendCommandContribution } from './hang-backend-command-contribution';
import { HangBackendService, HANG_BACKEND_BACKEND_SERVICE_PATH } from '../common/types';

export default new ContainerModule(bind => {
bind(HangBackendCommandContribution).toSelf().inSingletonScope();
bind(CommandContribution).toService(HangBackendCommandContribution);

bind(HangBackendService)
.toDynamicValue(
({ container }) => WebSocketConnectionProvider
.createProxy<HangBackendService>(container, HANG_BACKEND_BACKEND_SERVICE_PATH),
).inSingletonScope();
});
24 changes: 24 additions & 0 deletions packages/hang-backend/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/********************************************************************************
* Copyright (C) 2023 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

export const HANG_BACKEND_BACKEND_SERVICE_PATH = '/services/hang-backend-backend-service';

export const HangBackendService = Symbol('HangBackendService');

export interface HangBackendService {
hangBackend(timeout: number): void;
}

28 changes: 28 additions & 0 deletions packages/hang-backend/src/node/hang-backend-backend-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// *****************************************************************************
// Copyright (C) 2023 Ericsson and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************

import { ContainerModule } from '@theia/core/shared/inversify';
import { ConnectionHandler, JsonRpcConnectionHandler } from '@theia/core/lib/common/messaging';
import { HANG_BACKEND_BACKEND_SERVICE_PATH } from '../common/types';
import { HangBackendBackendService } from './hang-backend-backend-service';

export default new ContainerModule(bind => {
bind(HangBackendBackendService).toSelf().inSingletonScope();
bind(ConnectionHandler).toDynamicValue(({ container }) => new JsonRpcConnectionHandler<HangBackendBackendService>(
HANG_BACKEND_BACKEND_SERVICE_PATH,
() => container.get<HangBackendBackendService>(HangBackendBackendService),
));
});
31 changes: 31 additions & 0 deletions packages/hang-backend/src/node/hang-backend-backend-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// *****************************************************************************
// Copyright (C) 2023 Ericsson and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************

import { injectable } from '@theia/core/shared/inversify';
import { HangBackendService } from '../common/types';

@injectable()
export class HangBackendBackendService implements HangBackendService {
hangBackend(timeout: number): void {
const startingTime = Date.now();
while (true) {
if (Date.now() - startingTime >= timeout) {
break;
}
}
console.log('breaking out of loop');
}
}
16 changes: 16 additions & 0 deletions packages/hang-backend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../../configs/base.tsconfig",
"compilerOptions": {
"composite": true,
"rootDir": "src",
"outDir": "lib"
},
"include": [
"src"
],
"references": [
{
"path": "../core"
}
]
}
6 changes: 6 additions & 0 deletions packages/monaco/src/browser/monaco-editor-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import { Position, Range, TextDocumentSaveReason, TextDocumentContentChangeEvent } from '@theia/core/shared/vscode-languageserver-protocol';
import { TextEditorDocument, EncodingMode, FindMatchesOptions, FindMatch, EditorPreferences } from '@theia/editor/lib/browser';
import { ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';
import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { CancellationTokenSource, CancellationToken } from '@theia/core/lib/common/cancellation';
Expand Down Expand Up @@ -90,6 +91,7 @@ export class MonacoEditorModel implements IResolvedTextEditorModel, TextEditorDo
protected readonly resource: Resource,
protected readonly m2p: MonacoToProtocolConverter,
protected readonly p2m: ProtocolToMonacoConverter,
protected readonly connectionStatusService: ConnectionStatusService,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should get a 'breaking changes' mention.

protected readonly logger?: ILogger,
protected readonly editorPreferences?: EditorPreferences
) {
Expand All @@ -105,6 +107,10 @@ export class MonacoEditorModel implements IResolvedTextEditorModel, TextEditorDo
this.resolveModel = this.readContents().then(
content => this.initialize(content || '')
);
this.toDispose.push(this.connectionStatusService.onStatusChange(() => {
this.cancelSave();
this.cancelSync();
}));
Comment on lines +110 to +113
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The this is where the problem manifested itself, but I wonder if the the problem shouldn't be fixed in the FileResource code, since that's where the saving happens, and it's the connection to the backend file system that breaks saving / loading new content?

}

dispose(): void {
Expand Down
6 changes: 5 additions & 1 deletion packages/monaco/src/browser/monaco-editor-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { IBulkEditService } from '@theia/monaco-editor-core/esm/vs/editor/browse
import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
import { IQuickInputService } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/common/quickInput';
import { ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands';
import { ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';

export const MonacoEditorFactory = Symbol('MonacoEditorFactory');
export interface MonacoEditorFactory {
Expand Down Expand Up @@ -88,6 +89,9 @@ export class MonacoEditorProvider {
@inject(MonacoQuickInputImplementation)
protected readonly quickInputService: MonacoQuickInputImplementation;

@inject(ConnectionStatusService)
protected readonly connectionStatusService: ConnectionStatusService;

protected _current: MonacoEditor | undefined;
/**
* Returns the last focused MonacoEditor.
Expand Down Expand Up @@ -406,7 +410,7 @@ export class MonacoEditorProvider {
uri,
readContents: async () => '',
dispose: () => { }
}, this.m2p, this.p2m);
}, this.m2p, this.p2m, this.connectionStatusService);
toDispose.push(document);
const model = (await document.load()).textEditorModel;
return new MonacoEditor(
Expand Down
Loading