gristlabs_grist-core/app/server/lib/SafePythonComponent.ts
Dmitry S 51ff72c15e (core) Faster builds all around.
Summary:
Building:
- Builds no longer wait for tsc for either client, server, or test targets. All use esbuild which is very fast.
- Build still runs tsc, but only to report errors. This may be turned off with `SKIP_TSC=1` env var.
- Grist-core continues to build using tsc.
- Esbuild requires ES6 module semantics. Typescript's esModuleInterop is turned
  on, so that tsc accepts and enforces correct usage.
- Client-side code is watched and bundled by webpack as before (using esbuild-loader)

Code changes:
- Imports must now follow ES6 semantics: `import * as X from ...` produces a
  module object; to import functions or class instances, use `import X from ...`.
- Everything is now built with isolatedModules flag. Some exports were updated for it.

Packages:
- Upgraded browserify dependency, and related packages (used for the distribution-building step).
- Building the distribution now uses esbuild's minification. babel-minify is no longer used.

Test Plan: Should have no behavior changes, existing tests should pass, and docker image should build too.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Subscribers: alexmojaki

Differential Revision: https://phab.getgrist.com/D3506
2022-07-04 10:42:40 -04:00

71 lines
2.4 KiB
TypeScript

import {LocalPlugin} from 'app/common/plugin';
import {BaseComponent, createRpcLogger} from 'app/common/PluginInstance';
import {GristServer} from 'app/server/lib/GristServer';
import {ISandbox} from 'app/server/lib/ISandbox';
import log from 'app/server/lib/log';
import {IMsgCustom, IMsgRpcCall} from 'grain-rpc';
// TODO safePython component should be able to call other components function
// TODO calling a function on safePython component with a name that was not register chould fail
// gracefully.
/**
* The safePython component used by a PluginInstance.
*
* It uses `NSandbox` implementation of rpc for calling methods within the sandbox.
*/
export class SafePythonComponent extends BaseComponent {
private _sandbox?: ISandbox;
private _logMeta: log.ILogMeta;
// safe python component does not need pluginInstance.rpc because it is not possible to forward
// calls to other component from within python
constructor(_localPlugin: LocalPlugin,
private _tmpDir: string,
docName: string, private _server: GristServer,
rpcLogger = createRpcLogger(log, `PLUGIN ${_localPlugin.id} SafePython:`)) {
super(_localPlugin.manifest, rpcLogger);
this._logMeta = {plugin: _localPlugin.id, docId: docName};
}
/**
* `SafePythonComponent` activation creates the Sandbox. Throws if the plugin has no `safePyton`
* components.
*/
protected async activateImplementation(): Promise<void> {
if (!this._tmpDir) {
throw new Error("Sanbox should have a tmpDir");
}
this._sandbox = this._server.create.NSandbox({
importMount: this._tmpDir,
logTimes: true,
logMeta: this._logMeta,
});
}
protected async deactivateImplementation(): Promise<void> {
log.info('SafePython deactivating ...');
if (!this._sandbox) {
log.info(' sandbox is undefined');
}
if (this._sandbox) {
await this._sandbox.shutdown();
log.info('SafePython done deactivating the sandbox');
delete this._sandbox;
}
}
protected doForwardCall(c: IMsgRpcCall): Promise<any> {
if (!this._sandbox) { throw new Error("Component should have be activated"); }
const {meth, iface, args} = c;
const funcName = meth === "invoke" ? iface : iface + "." + meth;
return this._sandbox.pyCall(funcName, ...args);
}
protected doForwardMessage(c: IMsgCustom): Promise<any> {
throw new Error("Forwarding messages to python sandbox is not supported");
}
}