Skip to content

Commit

Permalink
squash-or-remove-me
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Maréchal <paul.marechal@ericsson.com>
  • Loading branch information
paul-marechal committed Mar 17, 2021
1 parent 4f5f145 commit 113bc84
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 83 deletions.
165 changes: 84 additions & 81 deletions packages/filesystem/src/node/filesystem-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,91 +33,20 @@ import { IPCConnectionProvider } from '@theia/core/lib/node';
import { JsonRpcProxyFactory, ConnectionErrorHandler } from '@theia/core';
import { FileSystemWatcherServiceDispatcher } from './filesystem-watcher-dispatcher';

const SINGLE_THREADED = process.argv.indexOf('--no-cluster') !== -1;
const NSFW_WATCHER_VERBOSE = process.argv.indexOf('--nsfw-watcher-verbose') !== -1;
export const NSFW_SINGLE_THREADED = process.argv.includes('--no-cluster');
export const NSFW_WATCHER_VERBOSE = process.argv.includes('--nsfw-watcher-verbose');

export interface FileWatcherSingleProcessOptions {
processType: 'single';
serverOptions: NsfwFileSystemWatcherServerOptions;
}

export interface FileWatcherMultiProcessOptions {
processType: 'multi';
export const NsfwFileSystemWatcherServiceProcessOptions = Symbol('NsfwFileSystemWatcherServiceProcessOptions');
/**
* Options to control the way the `NsfwFileSystemWatcherService` process is spawned.
*/
export interface NsfwFileSystemWatcherServiceProcessOptions {
/**
* Path to the script that will run the `NsfwFileSystemWatcherService` in a new process.
*/
entryPoint: string;
}

export const FileWatcherProcessOptions = Symbol('FileWatcherProcessOptions');
type FileWatcherProcessOptions = FileWatcherSingleProcessOptions | FileWatcherMultiProcessOptions;

export function bindFileSystemWatcherServer(bind: interfaces.Bind, { singleThreaded }: { singleThreaded: boolean } = { singleThreaded: SINGLE_THREADED }): void {
bind<NsfwOptions>(NsfwOptions).toConstantValue({});

bind(FileSystemWatcherServiceDispatcher).toSelf().inSingletonScope();

bind(FileSystemWatcherServerClient).toSelf();
bind(FileSystemWatcherServer).toService(FileSystemWatcherServerClient);

if (singleThreaded) {
bind<FileWatcherProcessOptions>(FileWatcherProcessOptions).toDynamicValue(ctx => {
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
return {
processType: 'single',
serverOptions: {
nsfwOptions,
verbose: NSFW_WATCHER_VERBOSE,
info: (message, ...args) => logger.info(message, ...args),
error: (message, ...args) => logger.error(message, ...args)
}
} as FileWatcherSingleProcessOptions;
}).inSingletonScope();
} else {
bind<FileWatcherProcessOptions>(FileWatcherProcessOptions).toConstantValue({
processType: 'multi',
entryPoint: path.resolve(__dirname, 'nsfw-watcher')
});
}

bind<FileSystemWatcherService>(FileSystemWatcherService).toDynamicValue(ctx => {
const watcherOptions = ctx.container.get<FileWatcherProcessOptions>(FileWatcherProcessOptions);
const dispatcher = ctx.container.get<FileSystemWatcherServiceDispatcher>(FileSystemWatcherServiceDispatcher);
if (watcherOptions.processType === 'single') {
// Bind and run the watch server in the current process:
const server = new NsfwFileSystemWatcherService(watcherOptions.serverOptions);
server.setClient(dispatcher);
return server;
} else {
// Run the watch server in a child process.
// Bind to a proxy forwarding calls to the child process.
const serverName = 'nsfw-watcher';
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
const ipcConnectionProvider = ctx.container.get<IPCConnectionProvider>(IPCConnectionProvider);
const proxyFactory = new JsonRpcProxyFactory<FileSystemWatcherService>();
const serverProxy = proxyFactory.createProxy();
// We need to call `.setClient` before listening, else the JSON-RPC calls won't go through.
serverProxy.setClient(dispatcher);
const args: string[] = [
`--nsfwOptions=${JSON.stringify(nsfwOptions)}`
];
if (NSFW_WATCHER_VERBOSE) {
args.push('--verbose');
}
ipcConnectionProvider.listen({
serverName,
entryPoint: watcherOptions.entryPoint,
errorHandler: new ConnectionErrorHandler({
serverName,
logger,
}),
env: process.env,
args,
}, connection => proxyFactory.listen(connection));
return serverProxy;
}
}).inSingletonScope();
}

export default new ContainerModule(bind => {
bind(EncodingService).toSelf().inSingletonScope();
bindFileSystemWatcherServer(bind);
Expand All @@ -136,3 +65,77 @@ export default new ContainerModule(bind => {
bind(NodeFileUploadService).toSelf().inSingletonScope();
bind(MessagingService.Contribution).toService(NodeFileUploadService);
});

export function bindFileSystemWatcherServer(bind: interfaces.Bind, { singleThreaded = NSFW_SINGLE_THREADED }: { singleThreaded?: boolean } = {}): void {
bind<NsfwOptions>(NsfwOptions).toConstantValue({});

bind(FileSystemWatcherServiceDispatcher).toSelf().inSingletonScope();

bind(FileSystemWatcherServerClient).toSelf();
bind(FileSystemWatcherServer).toService(FileSystemWatcherServerClient);

bind<NsfwFileSystemWatcherServiceProcessOptions>(NsfwFileSystemWatcherServiceProcessOptions).toConstantValue({
entryPoint: path.resolve(__dirname, 'nsfw-watcher'),
});
bind<NsfwFileSystemWatcherServerOptions>(NsfwFileSystemWatcherServerOptions).toDynamicValue(ctx => {
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
return {
nsfwOptions,
verbose: NSFW_WATCHER_VERBOSE,
info: (message, ...args) => logger.info(message, ...args),
error: (message, ...args) => logger.error(message, ...args),
};
}).inSingletonScope();

bind<FileSystemWatcherService>(FileSystemWatcherService).toDynamicValue(
ctx => singleThreaded
? createNsfwFileSystemWatcherService(ctx)
: spawnNsfwFileSystemWatcherServiceProcess(ctx)
).inSingletonScope();
}

/**
* Run the watch server in the current process.
*/
export function createNsfwFileSystemWatcherService(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<NsfwFileSystemWatcherServerOptions>(NsfwFileSystemWatcherServerOptions);
const dispatcher = ctx.container.get<FileSystemWatcherServiceDispatcher>(FileSystemWatcherServiceDispatcher);
const server = new NsfwFileSystemWatcherService(options);
server.setClient(dispatcher);
return server;
}

/**
* Run the watch server in a child process.
* Return a proxy forwarding calls to the child process.
*/
export function spawnNsfwFileSystemWatcherServiceProcess(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<NsfwFileSystemWatcherServiceProcessOptions>(NsfwFileSystemWatcherServiceProcessOptions);
const dispatcher = ctx.container.get<FileSystemWatcherServiceDispatcher>(FileSystemWatcherServiceDispatcher);
const serverName = 'nsfw-watcher';
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
const ipcConnectionProvider = ctx.container.get<IPCConnectionProvider>(IPCConnectionProvider);
const proxyFactory = new JsonRpcProxyFactory<FileSystemWatcherService>();
const serverProxy = proxyFactory.createProxy();
// We need to call `.setClient` before listening, else the JSON-RPC calls won't go through.
serverProxy.setClient(dispatcher);
const args: string[] = [
`--nsfwOptions=${JSON.stringify(nsfwOptions)}`
];
if (NSFW_WATCHER_VERBOSE) {
args.push('--verbose');
}
ipcConnectionProvider.listen({
serverName,
entryPoint: options.entryPoint,
errorHandler: new ConnectionErrorHandler({
serverName,
logger,
}),
env: process.env,
args,
}, connection => proxyFactory.listen(connection));
return serverProxy;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface NsfwWatcherOptions {
ignored: IMinimatch[]
}

export const NsfwFileSystemWatcherServerOptions = Symbol('NsfwFileSystemWatcherServerOptions');
export interface NsfwFileSystemWatcherServerOptions {
verbose: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -434,9 +435,9 @@ export class NsfwFileSystemWatcherService implements FileSystemWatcherService {
return watcherId;
}

protected createWatcher(clientId: number, fsPath: string, resolvedOptions: WatchOptions): NsfwWatcher {
protected createWatcher(clientId: number, fsPath: string, options: WatchOptions): NsfwWatcher {
const watcherOptions: NsfwWatcherOptions = {
ignored: resolvedOptions.ignored
ignored: options.ignored
.map(pattern => new Minimatch(pattern, { dot: true })),
};
return new NsfwWatcher(clientId, fsPath, watcherOptions, this.options, this.maybeClient);
Expand Down

0 comments on commit 113bc84

Please sign in to comment.