From 7078922a656d263700a1027b8ac6c17caea8b34a Mon Sep 17 00:00:00 2001 From: Paul Fitzpatrick Date: Wed, 27 Jul 2022 14:19:41 -0400 Subject: [PATCH] (core) ensure randomness works when sandbox is cloned from a checkpoint Summary: This calls a new `initialize` method on the sandbox before we start doing calculations with it, to make sure that `random.seed()` has been called. Otherwise, if the sandbox is cloned from a checkpoint, the seed will have been reset. The `initialize` method includes the functionality previously done by `set_doc_url` since it is also initialization/personalization and this way we avoid introducing another round trip to the sandbox. Test Plan: tested with grist-core configured to use gvisor Reviewers: georgegevoian, dsagal Reviewed By: georgegevoian, dsagal Subscribers: alexmojaki Differential Revision: https://phab.getgrist.com/D3549 --- app/server/lib/ActiveDoc.ts | 4 +--- sandbox/grist/functions/math.py | 4 ---- sandbox/grist/main.py | 11 +++++++++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/server/lib/ActiveDoc.ts b/app/server/lib/ActiveDoc.ts index a4f3d6f3..05ed380b 100644 --- a/app/server/lib/ActiveDoc.ts +++ b/app/server/lib/ActiveDoc.ts @@ -2059,9 +2059,7 @@ export class ActiveDoc extends EventEmitter { num_on_demand_tables: onDemandNames.length, }); - if (this._options?.docUrl) { - await this._pyCall('set_doc_url', this._options.docUrl); - } + await this._pyCall('initialize', this._options?.docUrl); // Calculations are not associated specifically with the user opening the document. // TODO: be careful with which users can create formulas. diff --git a/sandbox/grist/functions/math.py b/sandbox/grist/functions/math.py index e508fc62..b556fbba 100644 --- a/sandbox/grist/functions/math.py +++ b/sandbox/grist/functions/math.py @@ -15,10 +15,6 @@ from functions.info import ISNUMBER, ISLOGICAL from functions.unimplemented import unimplemented import roman -if os.environ.get("DETERMINISTIC_MODE"): - random.seed(1) - - # Iterates through elements of iterable arguments, or through individual args when not iterable. def _chain(*values_or_iterables): for v in values_or_iterables: diff --git a/sandbox/grist/main.py b/sandbox/grist/main.py index 58aa6985..f37b8997 100644 --- a/sandbox/grist/main.py +++ b/sandbox/grist/main.py @@ -3,6 +3,7 @@ This module defines what sandbox functions are made available to the Node contro and starts the grist sandbox. See engine.py for the API documentation. """ import os +import random import sys sys.path.append('thirdparty') # pylint: disable=wrong-import-position @@ -121,8 +122,14 @@ def run(sandbox): return schema.SCHEMA_VERSION @export - def set_doc_url(doc_url): - os.environ['DOC_URL'] = doc_url + def initialize(doc_url): + if os.environ.get("DETERMINISTIC_MODE"): + random.seed(1) + else: + # Make sure we have randomness, even if we are being cloned from a checkpoint + random.seed() + if doc_url: + os.environ['DOC_URL'] = doc_url @export def get_formula_error(table_id, col_id, row_id):