Skip to content

Commit

Permalink
check sandbox viability lazily
Browse files Browse the repository at this point in the history
This checks whether code can successfully run in the
sandbox only when the admin panel needs to report that,
rather than at start up. This is motivated by two things:

  - The desktop app became a lot slower to open with this
    check, since it uses pyodide by default, and there's
    been no work on optimizing the pyodide sandbox load
    times (as opposed to gvisor, where a lot of work was
    done, and it is also fundamentally faster).
  - The messages logged by a test sandbox starting and
    stopping have been confusing people.

There is a case for doing the check on startup, especially
on servers, so that we can fail early. Still, that isn't
what we were doing, and we'd also like to move away from the
server refusing to start because of a problem and
towards an always-reachable admin page that reports
the nature of problems in a clearer way.
  • Loading branch information
paulfitz committed Sep 25, 2024
1 parent ef6a04a commit 2d32dcc
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 16 deletions.
5 changes: 4 additions & 1 deletion app/client/ui/AdminPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,10 @@ Please log in as an administrator.`)),
const success = result?.status === 'success';
const details = result?.details as SandboxingBootProbeDetails|undefined;
if (!details) {
return cssValueLabel(t('unknown'));
// Sandbox details get filled out relatively slowly if
// this is first time on admin panel. So show "checking"
// if we don't have a reported status yet.
return cssValueLabel(result?.status ? t('unknown') : t('checking'));
}
const flavor = details.flavor;
const configured = details.configured;
Expand Down
6 changes: 0 additions & 6 deletions app/server/MergedServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,6 @@ export class MergedServer {
this.flexServer.checkOptionCombinations();
this.flexServer.summary();
this.flexServer.ready();

// Some tests have their timing perturbed by having this earlier
// TODO: update those tests.
if (this.hasComponent("docs")) {
await this.flexServer.checkSandbox();
}
} catch(e) {
await this.flexServer.close();
throw e;
Expand Down
2 changes: 1 addition & 1 deletion app/server/lib/BootProbes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ const _sandboxingProbe: Probe = {
id: 'sandboxing',
name: 'Is document sandboxing effective',
apply: async (server, req) => {
const details = server.getSandboxInfo();
const details = await server.getSandboxInfo();
return {
status: (details?.configured && details?.functional) ? 'success' : 'fault',
details,
Expand Down
12 changes: 6 additions & 6 deletions app/server/lib/FlexServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1386,8 +1386,9 @@ export class FlexServer implements GristServer {
}
}

public async checkSandbox() {
if (this._check('sandbox', 'doc')) { return; }
public async getSandboxInfo(): Promise<SandboxInfo|undefined> {
if (this._sandboxInfo) { return this._sandboxInfo; }

const flavor = process.env.GRIST_SANDBOX_FLAVOR || 'unknown';
const info = this._sandboxInfo = {
flavor,
Expand All @@ -1397,6 +1398,8 @@ export class FlexServer implements GristServer {
sandboxed: false,
lastSuccessfulStep: 'none',
} as SandboxInfo;
// Only meaningful on instances that handle documents.
if (!this._docManager) { return info; }
try {
const sandbox = createSandbox({
server: this,
Expand All @@ -1421,10 +1424,7 @@ export class FlexServer implements GristServer {
} catch (e) {
info.error = String(e);
}
}

public getSandboxInfo(): SandboxInfo|undefined {
return this._sandboxInfo;
return info;
}

public getInfo(key: string): any {
Expand Down
4 changes: 2 additions & 2 deletions app/server/lib/GristServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface GristServer {
servesPlugins(): boolean;
getBundledWidgets(): ICustomWidget[];
getBootKey(): string|undefined;
getSandboxInfo(): SandboxInfo|undefined;
getSandboxInfo(): Promise<SandboxInfo|undefined>;
getInfo(key: string): any;
}

Expand Down Expand Up @@ -163,7 +163,7 @@ export function createDummyGristServer(): GristServer {
getPlugins() { return []; },
getBundledWidgets() { return []; },
getBootKey() { return undefined; },
getSandboxInfo() { return undefined; },
getSandboxInfo() { return Promise.resolve(undefined); },
getInfo(key: string) { return undefined; }
};
}
Expand Down

0 comments on commit 2d32dcc

Please sign in to comment.