Skip to content

Commit

Permalink
[workspace] Better localstorage keys eclipse-theia#904
Browse files Browse the repository at this point in the history
Because Theia is both meant to roll on a local machine and in the cloud, this commit adds better browser localstorage
keys, so that Theia gets less confused as to what is being displayed in case that some URI points to different remotes
(reverse proxying the same URL -at different times- to different theia instances).

This ensures that despite sharing the same local storage domain (host:port), multiple theias can be differentiated by passing a
`--domain` argument. This means that we can identify different theias behind proxies, as long as the instances are run with a
different `--domain <id>`.

When this domain is not specified, then theia will use `window.location.pathname`.

Signed-off-by: Paul Maréchal <[email protected]>
  • Loading branch information
paul-marechal committed Apr 19, 2018
1 parent da4e14a commit 79ad53e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
4 changes: 4 additions & 0 deletions packages/workspace/src/browser/workspace-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export class WorkspaceService implements FrontendApplicationContribution {
this.deferredRoot.resolve(this._root);
}

async getDomain(): Promise<string | undefined> {
return this.server.getDomain();
}

protected updateTitle(uri: URI): void {
document.title = uri.displayName;
}
Expand Down
28 changes: 18 additions & 10 deletions packages/workspace/src/browser/workspace-storage-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import { StorageService } from '@theia/core/lib/browser/storage-service';
import { WorkspaceService } from './workspace-service';
import { inject, injectable } from 'inversify';
import { inject, injectable, postConstruct } from 'inversify';
import { ILogger } from '@theia/core/lib/common';
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
import URI from '@theia/core/lib/common/uri';

/*
* Prefixes any stored data with the current workspace path.
Expand All @@ -21,18 +22,25 @@ export class WorkspaceStorageService implements StorageService {
private initialized: Promise<void>;
protected storageService: StorageService;

constructor( @inject(WorkspaceService) protected workspaceService: WorkspaceService,
@inject(ILogger) protected logger: ILogger) {
this.initialized = this.workspaceService.root.then(stat => {
if (stat) {
this.prefix = stat.uri;
} else {
this.prefix = '_global_';
}
});
@inject(WorkspaceService)
protected workspaceService: WorkspaceService;

@inject(ILogger)
protected logger: ILogger;

constructor() {
this.storageService = new LocalStorageService(this.logger);
}

@postConstruct()
protected async init(): Promise<void> {
const domain = await this.workspaceService.getDomain();
const statFile = await this.workspaceService.root;
const workspace = statFile ? new URI(statFile.uri).path : '_global_';
this.prefix = `${domain ? domain : window.location.pathname}:${workspace}`;
this.initialized = Promise.resolve();
}

async setData<T>(key: string, data: T): Promise<void> {
if (!this.prefix) {
await this.initialized;
Expand Down
2 changes: 2 additions & 0 deletions packages/workspace/src/common/test/mock-workspace-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { WorkspaceServer } from '../workspace-protocol';
@injectable()
export class MockWorkspaceServer implements WorkspaceServer {

getDomain(): Promise<string | undefined> { return Promise.resolve('mock'); }

getRoot(): Promise<string | undefined> { return Promise.resolve(''); }

setRoot(uri: string): Promise<void> { return Promise.resolve(); }
Expand Down
5 changes: 5 additions & 0 deletions packages/workspace/src/common/workspace-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export const workspacePath = '/services/workspace';
export const WorkspaceServer = Symbol('WorkspaceServer');
export interface WorkspaceServer {

/**
* Returns the random identifier to the running theia instance
*/
getDomain(): Promise<string | undefined>;

/**
* Returns with a promise that resolves to the workspace root URI as a string. Resolves to `undefined` if the workspace root is not yet set.
*/
Expand Down
30 changes: 19 additions & 11 deletions packages/workspace/src/node/default-workspace-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as yargs from 'yargs';
import * as fs from 'fs-extra';
import * as os from 'os';

import { injectable, inject } from "inversify";
import { injectable, inject, postConstruct } from "inversify";
import { FileUri } from '@theia/core/lib/node';
import { CliContribution } from '@theia/core/lib/node/cli';
import { Deferred } from '@theia/core/lib/common/promise-util';
Expand All @@ -20,15 +20,19 @@ import { WorkspaceServer } from "../common";
export class WorkspaceCliContribution implements CliContribution {

workspaceRoot = new Deferred<string | undefined>();
domain?: string;

configure(conf: yargs.Argv): void {
conf.usage("$0 [workspace-directory] [options]");
conf.option('root-dir', {
description: 'DEPRECATED: Sets the workspace directory.',
});
conf.option('domain', { description: 'The domain id-like to represent', type: 'string' });
}

setArguments(args: yargs.Arguments): void {
this.domain = args.domain;

let wsPath = args._[2];
if (!wsPath) {
wsPath = args['root-dir'];
Expand All @@ -50,18 +54,22 @@ export class DefaultWorkspaceServer implements WorkspaceServer {

protected root: Promise<string | undefined>;

constructor(
@inject(WorkspaceCliContribution) protected readonly cliParams: WorkspaceCliContribution
) {
@inject(WorkspaceCliContribution)
protected readonly cliParams: WorkspaceCliContribution;

@postConstruct()
protected async init(): Promise<void> {
this.root = this.getRootURIFromCli();
this.root.then(async root => {
if (!root) {
const data = await this.readFromUserHome();
if (data && data.recentRoots) {
this.root = Promise.resolve(data.recentRoots[0]);
}
if (!await this.root) {
const data = await this.readFromUserHome();
if (data && data.recentRoots) {
this.root = Promise.resolve(data.recentRoots[0]);
}
});
}
}

async getDomain(): Promise<string | undefined> {
return Promise.resolve(this.cliParams.domain);
}

getRoot(): Promise<string | undefined> {
Expand Down

0 comments on commit 79ad53e

Please sign in to comment.