Skip to content

Commit 3290d47

Browse files
committed
Revert hang fixes
1 parent 4f88f85 commit 3290d47

1 file changed

Lines changed: 47 additions & 90 deletions

File tree

python/scripts/run_emscripten_tests.py

Lines changed: 47 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,8 @@ def do_GET(self) -> bytes | None:
6767
evt.data.print.forEach((x)=>{window.python_logs.push(x)});
6868
}
6969
}
70-
function startPyWorker() {
71-
window.pyworker_failed = false;
72-
window.pyworker = new Worker("worker.js");
73-
window.pyworker.onmessage = capturelogs;
74-
window.pyworker.onerror = (evt) => {
75-
window.pyworker_failed = true;
76-
window.python_logs.push(...new TextEncoder().encode(
77-
`Worker error: ${evt.message}\n`));
78-
if (window.python_done_callback) {
79-
let callback = window.python_done_callback;
80-
window.python_done_callback = undefined;
81-
callback({result: 1});
82-
}
83-
};
84-
}
85-
startPyWorker();
70+
window.pyworker = new Worker("worker.js");
71+
window.pyworker.onmessage = capturelogs;
8672
</script>
8773
</head>
8874
<body></body>
@@ -96,28 +82,22 @@ def do_GET(self) -> bytes | None:
9682
elif self.path.endswith("/worker.js"):
9783
body = b"""
9884
importScripts("./pyodide.js");
99-
function do_print(arg) {
100-
let databytes = Array.from(arg);
101-
self.postMessage({print:databytes});
102-
return databytes.length;
103-
}
10485
onmessage = async function (e) {
10586
const data = e.data;
106-
try {
107-
if (!self.pyodide) {
108-
self.pyodide = await loadPyodide();
109-
}
110-
self.pyodide.setStdout({write:do_print,isatty:data.isatty});
111-
self.pyodide.setStderr({write:do_print,isatty:data.isatty});
112-
113-
await self.pyodide.loadPackagesFromImports(data.python);
114-
let results = await self.pyodide.runPythonAsync(data.python);
115-
self.postMessage({results});
116-
} catch (error) {
117-
do_print(new TextEncoder().encode(
118-
`Worker failed: ${error && error.stack || error}\n`));
119-
self.postMessage({results: 1});
87+
if (!self.pyodide) {
88+
self.pyodide = await loadPyodide();
89+
}
90+
function do_print(arg) {
91+
let databytes = Array.from(arg);
92+
self.postMessage({print:databytes});
93+
return databytes.length;
12094
}
95+
self.pyodide.setStdout({write:do_print,isatty:data.isatty});
96+
self.pyodide.setStderr({write:do_print,isatty:data.isatty});
97+
98+
await self.pyodide.loadPackagesFromImports(data.python);
99+
let results = await self.pyodide.runPythonAsync(data.python);
100+
self.postMessage({results});
121101
}
122102
"""
123103
self.send_response(200)
@@ -222,78 +202,56 @@ class BrowserDriver:
222202
def __init__(self, hostname, port, driver):
223203
self.driver = driver
224204
self.driver.get(f"http://{hostname}:{port}/test.html")
205+
# Chrome on CI takes longer than locally to compile.
206+
self.driver.set_script_timeout(1200)
225207

226208
def load_pyodide(self, dist_dir):
227209
pass
228210

229211
def load_arrow(self):
230-
code = (f"import pyodide_js as pjs\n"
231-
f"await pjs.loadPackage('{PYARROW_WHEEL_PATH.name}')\n")
232-
for attempt in range(3):
233-
try:
234-
result = self.execute_python(code, timeout=300)
235-
if result:
236-
raise RuntimeError(
237-
"PyArrow wheel failed to load in browser "
238-
f"(exit status {result}), see log above")
239-
return result
240-
except TimeoutError:
241-
if attempt == 2:
242-
raise TimeoutError(
243-
"Timed out initializing Pyodide/PyArrow in browser")
244-
print("Timed out initializing Pyodide/loading PyArrow. Restarting",
245-
flush=True)
246-
self.restart_worker()
247-
248-
def execute_python(self, code, wait_for_terminate=True, timeout=None):
249-
self.driver.execute_script(
250-
f"""
251-
let python = `{code}`;
252-
delete window.python_script_done;
253-
window.python_done_callback= (x) => {{window.python_script_done=x;}};
254-
window.pyworker.postMessage(
255-
{{python,isatty:{'true' if sys.stdout.isatty() else 'false'}}});
256-
"""
212+
self.execute_python(
213+
f"import pyodide_js as pjs\n"
214+
f"await pjs.loadPackage('{PYARROW_WHEEL_PATH.name}')\n"
257215
)
258-
if wait_for_terminate:
259-
return self.wait_for_done(timeout=timeout)
260216

261-
def restart_worker(self):
262-
self.driver.execute_script(
263-
"window.pyworker.terminate(); startPyWorker(); "
264-
"delete window.python_script_done; window.python_done_callback = undefined;"
265-
)
217+
def execute_python(self, code, wait_for_terminate=True):
218+
if wait_for_terminate:
219+
self.driver.execute_async_script(
220+
f"""
221+
let callback = arguments[arguments.length-1];
222+
python = `{code}`;
223+
window.python_done_callback = callback;
224+
window.pyworker.postMessage(
225+
{{python, isatty: {'true' if sys.stdout.isatty() else 'false'}}});
226+
"""
227+
)
228+
else:
229+
self.driver.execute_script(
230+
f"""
231+
let python = `{code}`;
232+
window.python_done_callback= (x) => {{window.python_script_done=x;}};
233+
window.pyworker.postMessage(
234+
{{python,isatty:{'true' if sys.stdout.isatty() else 'false'}}});
235+
"""
236+
)
266237

267238
def clear_logs(self):
268239
self.driver.execute_script("window.python_logs = [];")
269240

270-
def wait_for_done(self, timeout=None):
271-
start = last_heartbeat = time.monotonic()
241+
def wait_for_done(self):
272242
while True:
273243
# poll for console.log messages from our webworker
274-
# (output of pytest), completion and worker death
275-
state = self.driver.execute_script(
276-
"let logs = window.python_logs; window.python_logs = [];"
277-
"return {logs: logs, done: window.python_script_done,"
278-
" failed: window.pyworker_failed === true};"
244+
# which are the output of pytest
245+
lines = self.driver.execute_script(
246+
"let temp = window.python_logs;window.python_logs=[];return temp;"
279247
)
280-
lines = state.get("logs") or []
281248
if len(lines) > 0:
282249
sys.stdout.buffer.write(bytes(lines))
283-
sys.stdout.buffer.flush()
284-
done = state.get("done")
250+
done = self.driver.execute_script("return window.python_script_done;")
285251
if done is not None:
252+
value = done["result"]
286253
self.driver.execute_script("delete window.python_script_done;")
287-
return done["result"]
288-
if state.get("failed"):
289-
raise RuntimeError(
290-
"Browser-side worker died. See 'Worker error:' in log above")
291-
now = time.monotonic()
292-
if timeout is not None and now - start > timeout:
293-
raise TimeoutError
294-
if now - last_heartbeat > 30:
295-
print("Waiting for browser-side Python to finish...", flush=True)
296-
last_heartbeat = now
254+
return value
297255
time.sleep(0.1)
298256

299257

@@ -304,7 +262,6 @@ def __init__(self, hostname, port):
304262
options = Options()
305263
options.add_argument("--headless")
306264
options.add_argument("--no-sandbox")
307-
options.add_argument("--disable-dev-shm-usage")
308265
driver = webdriver.Chrome(options=options)
309266
driver.command_executor._client_config.timeout = 1200
310267
super().__init__(hostname, port, driver)

0 commit comments

Comments
 (0)