提交 c6be0b54 编写于 作者: B Benjamin Pasero

remote - adopt readFileStream capability

上级 6f823003
......@@ -32,15 +32,20 @@ export interface IWatcherOptions {
usePolling: boolean;
}
export interface IDiskFileSystemProviderOptions {
bufferSize?: number;
watcher?: IWatcherOptions;
}
export class DiskFileSystemProvider extends Disposable implements
IFileSystemProviderWithFileReadWriteCapability,
IFileSystemProviderWithOpenReadWriteCloseCapability,
IFileSystemProviderWithFileReadStreamCapability,
IFileSystemProviderWithFileFolderCopyCapability {
private readonly BUFFER_SIZE = 64 * 1024;
private readonly BUFFER_SIZE = this.options?.bufferSize || 64 * 1024;
constructor(private logService: ILogService, private watcherOptions?: IWatcherOptions) {
constructor(private logService: ILogService, private options?: IDiskFileSystemProviderOptions) {
super();
}
......@@ -558,9 +563,9 @@ export class DiskFileSystemProvider extends Disposable implements
let watcherOptions: IWatcherOptions | undefined = undefined;
// requires a polling watcher
if (this.watcherOptions && this.watcherOptions.usePolling) {
if (this.options?.watcher?.usePolling) {
watcherImpl = UnixWatcherService;
watcherOptions = this.watcherOptions;
watcherOptions = this.options?.watcher;
}
// Single Folder Watcher
......
......@@ -8,10 +8,13 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'
import { URI, UriComponents } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { FileChangeType, FileDeleteOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, IFileChange, IStat, IWatchOptions, FileOpenOptions, IFileSystemProviderWithFileReadWriteCapability, FileWriteOptions } from 'vs/platform/files/common/files';
import { FileChangeType, FileDeleteOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, IFileChange, IStat, IWatchOptions, FileOpenOptions, IFileSystemProviderWithFileReadWriteCapability, FileWriteOptions, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileFolderCopyCapability, FileReadStreamOptions, IFileSystemProviderWithOpenReadWriteCloseCapability } from 'vs/platform/files/common/files';
import { VSBuffer } from 'vs/base/common/buffer';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
import { OperatingSystem } from 'vs/base/common/platform';
import { newWriteableStream, ReadableStreamEvents, ReadableStreamEventPayload } from 'vs/base/common/stream';
import { CancellationToken } from 'vs/base/common/cancellation';
import { canceled } from 'vs/base/common/errors';
export const REMOTE_FILE_SYSTEM_CHANNEL_NAME = 'remotefilesystem';
......@@ -20,7 +23,11 @@ export interface IFileChangeDto {
type: FileChangeType;
}
export class RemoteExtensionsFileSystemProvider extends Disposable implements IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileReadWriteCapability {
export class RemoteFileSystemProvider extends Disposable implements
IFileSystemProviderWithFileReadWriteCapability,
IFileSystemProviderWithOpenReadWriteCloseCapability,
IFileSystemProviderWithFileReadStreamCapability,
IFileSystemProviderWithFileFolderCopyCapability {
private readonly session: string = generateUuid();
......@@ -46,7 +53,7 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF
}
private registerListeners(): void {
this._register(this.channel.listen<IFileChangeDto[] | string>('filechange', [this.session])((eventsOrError) => {
this._register(this.channel.listen<IFileChangeDto[] | string>('filechange', [this.session])(eventsOrError => {
if (Array.isArray(eventsOrError)) {
const events = eventsOrError;
this._onDidChange.fire(events.map(event => ({ resource: URI.revive(event.resource), type: event.type })));
......@@ -61,6 +68,7 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF
let capabilities = (
FileSystemProviderCapabilities.FileReadWrite
| FileSystemProviderCapabilities.FileOpenReadWriteClose
| FileSystemProviderCapabilities.FileReadStream
| FileSystemProviderCapabilities.FileFolderCopy
);
......@@ -100,9 +108,47 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF
async readFile(resource: URI): Promise<Uint8Array> {
const buff = <VSBuffer>await this.channel.call('readFile', [resource]);
return buff.buffer;
}
readFileStream(resource: URI, opts: FileReadStreamOptions, token?: CancellationToken): ReadableStreamEvents<Uint8Array> {
const stream = newWriteableStream<Uint8Array>(data => VSBuffer.concat(data.map(data => VSBuffer.wrap(data))).buffer);
// Reading as file stream goes through an event to the remote side
const listener = this.channel.listen<ReadableStreamEventPayload<VSBuffer>>('readFileStream', [resource, opts])(dataOrErrorOrEnd => {
if (dataOrErrorOrEnd instanceof VSBuffer) {
// data: forward into the stream
stream.write(dataOrErrorOrEnd.buffer);
} else {
// error / end: always end the stream on errors too
stream.end(dataOrErrorOrEnd === 'end' ? undefined : dataOrErrorOrEnd);
// Signal to the remote side that we no longer listen
listener.dispose();
}
});
// Support cancellation
if (token) {
Event.once(token.onCancellationRequested)(() => {
// Ensure to end the stream properly with an error
// to indicate the cancellation.
stream.end(canceled());
// Ensure to dispose the listener upon cancellation. This will
// bubble through the remote side as event and allows to stop
// reading the file.
listener.dispose();
});
}
return stream;
}
write(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
return this.channel.call('write', [fd, pos, VSBuffer.wrap(data), offset, length]);
}
......
......@@ -11,7 +11,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { Workbench } from 'vs/workbench/browser/workbench';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel';
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IProductService } from 'vs/platform/product/common/productService';
import product from 'vs/platform/product/common/product';
......@@ -238,7 +238,7 @@ class BrowserMain extends Disposable {
// Remote file system
const channel = connection.getChannel<IChannel>(REMOTE_FILE_SYSTEM_CHANNEL_NAME);
const remoteFileSystemProvider = this._register(new RemoteExtensionsFileSystemProvider(channel, remoteAgentService.getEnvironment()));
const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(channel, remoteAgentService.getEnvironment()));
fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider);
if (!this.configuration.userDataProvider) {
......
......@@ -43,7 +43,7 @@ import { FileService } from 'vs/platform/files/common/fileService';
import { IFileService } from 'vs/platform/files/common/files';
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel';
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel';
import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache';
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
import { SignService } from 'vs/platform/sign/node/signService';
......@@ -217,7 +217,7 @@ class DesktopMain extends Disposable {
const connection = remoteAgentService.getConnection();
if (connection) {
const channel = connection.getChannel<IChannel>(REMOTE_FILE_SYSTEM_CHANNEL_NAME);
const remoteFileSystemProvider = this._register(new RemoteExtensionsFileSystemProvider(channel, remoteAgentService.getEnvironment()));
const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(channel, remoteAgentService.getEnvironment()));
fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册