Skip to content

Commit

Permalink
with dedicated web socket
Browse files Browse the repository at this point in the history
  • Loading branch information
akosyakov committed May 13, 2019
1 parent 38f4ea6 commit 1e0ca14
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 221 deletions.
2 changes: 0 additions & 2 deletions packages/filesystem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
"description": "Theia - FileSystem Extension",
"dependencies": {
"@theia/core": "^0.6.0",
"@types/base64-js": "^1.2.5",
"@types/body-parser": "^1.17.0",
"@types/fs-extra": "^4.0.2",
"@types/mime-types": "^2.1.0",
"@types/rimraf": "^2.0.2",
"@types/tar-fs": "^1.16.1",
"@types/touch": "0.0.1",
"@types/uuid": "^3.4.3",
"base64-js": "^1.2.1",
"body-parser": "^1.18.3",
"drivelist": "^6.4.3",
"fs-extra": "^4.0.2",
Expand Down
121 changes: 49 additions & 72 deletions packages/filesystem/src/browser/file-upload-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@

// tslint:disable:no-any

import * as base64 from 'base64-js';
import { injectable, inject, postConstruct } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { CancellationTokenSource, CancellationToken, checkCancelled } from '@theia/core/lib/common/cancellation';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { MessageService } from '@theia/core/lib/common/message-service';
import { Progress } from '@theia/core/src/common/message-service-protocol';
import { FileUploadServer } from '../common/file-upload-server';
import { Progress } from '@theia/core/lib/common/message-service-protocol';
import { Endpoint } from '@theia/core/lib/browser/endpoint';

const maxChunkSize = 64 * 1024;

Expand All @@ -48,9 +47,6 @@ export class FileUploadService {
@inject(MessageService)
protected readonly messageService: MessageService;

@inject(FileUploadServer)
protected readonly uploadServer: FileUploadServer;

protected uploadForm: FileUploadService.Form;

@postConstruct()
Expand Down Expand Up @@ -116,69 +112,63 @@ export class FileUploadService {
if (!entries.length) {
return result;
}
const total = totalSize;
let done = 0;
for (const entry of entries) {
progress.report({ work: { done, total } });
const { file } = entry;
let id: string | undefined;
let readBytes = 0;
let someAppendFailed: Error | undefined;
const deferredUpload = new Deferred<FileUploadResult>();
const endpoint = new Endpoint({ path: '/file-upload' });
const socket = new WebSocket(endpoint.getWebSocketUrl().toString());
socket.onerror = deferredUpload.reject;
socket.onclose = ({ code, reason }) => deferredUpload.reject(new Error(String(reason || code)));
socket.onmessage = ({ data }) => {
const response = JSON.parse(data);
if (response.progress) {
const { done, total } = response.progress;
progress.report({ work: { done, total } });
return;
}
if (response.ok) {
deferredUpload.resolve(result);
} else if (response.error) {
deferredUpload.reject(new Error(response.error));
} else {
console.error('unknown upload response: ' + response);
}
socket.close();
};
socket.onopen = async () => {
try {
const promises: Promise<void>[] = [];
do {
const fileSlice = await this.readFileSlice(file, readBytes);
if (someAppendFailed) {
throw someAppendFailed;
}
checkCancelled(token);
readBytes = fileSlice.read;
if (id === undefined) {
id = await this.uploadServer.open(entry.uri.toString(), fileSlice.content, readBytes >= file.size);
checkCancelled(token);
progress.report({
work: {
done: done + fileSlice.read,
total
}
});
} else {
promises.push(this.uploadServer.append(id, fileSlice.content, readBytes >= file.size).then(() => {
const total = totalSize;
socket.send(JSON.stringify({ total }));
for (const entry of entries) {
const { file } = entry;
let readBytes = 0;
socket.send(JSON.stringify({ uri: entry.uri.toString(), size: file.size }));
if (file.size) {
do {
const fileSlice = await this.readFileSlice(file, readBytes);
checkCancelled(token);
progress.report({
work: {
done: done + fileSlice.read,
total
}
});
}, appendError => {
someAppendFailed = appendError;
throw appendError;
}));
readBytes = fileSlice.read;
socket.send(fileSlice.content);
while (socket.bufferedAmount > maxChunkSize * 2) {
await new Promise(resolve => setTimeout(resolve));
checkCancelled(token);
}
} while (readBytes < file.size);
}
} while (readBytes < file.size);
await Promise.all(promises);
done += file.size;
progress.report({ work: { done, total } });
} finally {
if (id !== undefined) {
this.uploadServer.close(id);
}
} catch (e) {
deferredUpload.reject(e);
if (socket.readyState === 1) {
socket.close();
}
}
}
progress.report({ work: { done: total, total } });
return result;
};
return deferredUpload.promise;
}

protected readFileSlice(file: File, read: number): Promise<{
content: string
content: ArrayBuffer
read: number
}> {
return new Promise((resolve, reject) => {
if (file.size === 0 && read === 0) {
resolve({ content: '', read });
return;
}
const bytesLeft = file.size - read;
if (!bytesLeft) {
reject(new Error('nothing to read'));
Expand All @@ -189,8 +179,7 @@ export class FileUploadService {
const reader = new FileReader();
reader.onload = () => {
read += size;
const buffer = reader.result as ArrayBuffer;
const content = base64.fromByteArray(new Uint8Array(buffer));
const content = reader.result as ArrayBuffer;
resolve({ content, read });
};
reader.onerror = reject;
Expand Down Expand Up @@ -321,22 +310,10 @@ export namespace FileUploadService {
token: CancellationToken
entries: UploadEntry[]
totalSize: number

}
export interface Form {
targetInput: HTMLInputElement
fileInput: HTMLInputElement
progress?: FileUploadProgressParams
}
export interface SubmitOptions {
body: FormData
token: CancellationToken
onDidProgress: (event: ProgressEvent) => void
}
export interface SubmitError extends Error {
status: number;
}
export function isSubmitError(e: any): e is SubmitError {
return !!e && 'status' in e;
}
}
6 changes: 0 additions & 6 deletions packages/filesystem/src/browser/filesystem-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { FileSystemWatcher } from './filesystem-watcher';
import { FileSystemFrontendContribution } from './filesystem-frontend-contribution';
import { FileSystemProxyFactory } from './filesystem-proxy-factory';
import { FileUploadService } from './file-upload-service';
import { fileUploadPath, FileUploadServer } from '../common/file-upload-server';

export default new ContainerModule(bind => {
bindFileSystemPreferences(bind);
Expand Down Expand Up @@ -63,11 +62,6 @@ export default new ContainerModule(bind => {
bind(FileSystemFrontendContribution).toSelf().inSingletonScope();
bind(CommandContribution).toService(FileSystemFrontendContribution);
bind(FrontendApplicationContribution).toService(FileSystemFrontendContribution);

bind(FileUploadServer).toDynamicValue(ctx => {
const provider = ctx.container.get(WebSocketConnectionProvider);
return provider.createProxy<FileUploadServer>(fileUploadPath);
}).inSingletonScope();
});

export function bindFileResource(bind: interfaces.Bind): void {
Expand Down
27 changes: 0 additions & 27 deletions packages/filesystem/src/common/file-upload-server.ts

This file was deleted.

15 changes: 4 additions & 11 deletions packages/filesystem/src/node/filesystem-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { FileSystem, FileSystemClient, fileSystemPath, DispatchingFileSystemClie
import { FileSystemWatcherServer, FileSystemWatcherClient, fileSystemWatcherPath } from '../common/filesystem-watcher-protocol';
import { FileSystemWatcherServerClient } from './filesystem-watcher-client';
import { NsfwFileSystemWatcherServer } from './nsfw-watcher/nsfw-filesystem-watcher';
import { fileUploadPath, FileUploadServer } from '../common/file-upload-server';
import { NodeFileUploadServer } from './node-file-upload-server';
import { MessagingService } from '@theia/core/lib/node/messaging/messaging-service';
import { NodeFileUploadService } from './node-file-upload-service';

const SINGLE_THREADED = process.argv.indexOf('--no-cluster') !== -1;

Expand Down Expand Up @@ -82,13 +82,6 @@ export default new ContainerModule(bind => {
})
).inSingletonScope();

bind(NodeFileUploadServer).toSelf().inTransientScope();
bind(FileUploadServer).toService(NodeFileUploadServer);
bind(ConnectionHandler).toDynamicValue(ctx =>
new JsonRpcConnectionHandler(fileUploadPath, client => {
const server = ctx.container.get<FileUploadServer>(FileUploadServer);
client.onDidCloseConnection(() => server.dispose());
return server;
})
).inSingletonScope();
bind(NodeFileUploadService).toSelf().inSingletonScope();
bind(MessagingService.Contribution).toService(NodeFileUploadService);
});
98 changes: 0 additions & 98 deletions packages/filesystem/src/node/node-file-upload-server.ts

This file was deleted.

Loading

0 comments on commit 1e0ca14

Please sign in to comment.