Revert "Make `asyncio.sleep(0)` run faster (#4568)" (#4583)

This commit is contained in:
Gyeongjae Choi 2024-03-01 12:22:03 +09:00 committed by GitHub
parent 2731e22844
commit f2411848f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 3 additions and 73 deletions

View File

@ -54,9 +54,6 @@ myst:
- {{ Enhancement }} Fixed a memory leak when iterating over a PyProxy.
{pr}`4546`
- {{ Enhancement }} `asyncio.sleep(0)` now runs the next task a lot faster.
{pr}`4568`
- {{ Fix }} `pyodide.mountNativeFS` will no longer silently overwrite an
existing nonempty directory. Also it throws much clearer error messages when
it fails.

View File

@ -31,7 +31,6 @@ module = [
"matplotlib.*",
"PIL.*",
"pyodide_js",
"pyodide_js._api",
"pytest_pyodide",
"pytest_pyodide.runner",
"pytest_pyodide.utils",

View File

@ -8,7 +8,6 @@ import { type PyProxy, type PyDict } from "generated/pyproxy";
import { loadBinaryFile, nodeFSMod } from "./compat";
import { version } from "./version";
import { setStdin, setStdout, setStderr } from "./streams";
import { scheduleCallback } from "./scheduler";
import { TypedArray } from "./types";
import { IN_NODE } from "./environments";
@ -52,10 +51,6 @@ API.saveState = () => API.pyodide_py._state.save_state();
/** @private */
API.restoreState = (state: any) => API.pyodide_py._state.restore_state(state);
// Used in webloop
/** @private */
API.scheduleCallback = scheduleCallback;
function ensureMountPathExists(path: string): void {
Module.FS.mkdirTree(path);
const { node } = Module.FS.lookupPath(path, {

View File

@ -81,7 +81,7 @@
"scripts": {
"build": "tsc --noEmit && node esbuild.config.mjs",
"test": "npm-run-all test:*",
"test:unit": "cross-env TEST_NODE=1 ts-mocha --exit --node-option=experimental-loader=./test/loader.mjs --node-option=experimental-wasm-stack-switching -p tsconfig.test.json test/unit/**/*.test.*",
"test:unit": "cross-env TEST_NODE=1 ts-mocha --node-option=experimental-loader=./test/loader.mjs --node-option=experimental-wasm-stack-switching -p tsconfig.test.json test/unit/**/*.test.*",
"test:node": "cross-env TEST_NODE=1 mocha test/integration/**/*.test.js",
"test:browser": "mocha test/integration/**/*.test.js",
"tsc": "tsc --noEmit",

View File

@ -1,19 +0,0 @@
/**
* Schedule a callback. Supports both immediate and delayed callbacks.
* @param callback The callback to be scheduled
* @param timeout The delay in milliseconds before the callback is called
*/
export function scheduleCallback(callback: () => void, timeout: number = 0) {
// In modern browsers, setTimeout has throttling minimum delay (mostly 4ms).
// So to support immediate callbacks, we use MessageChannel if the delay is less than 4ms.
// Ref0: https://github.com/pyodide/pyodide/issues/4006
// Ref1: (firefox) https://developer.mozilla.org/en-US/docs/Web/API/setTimeout
// Ref2: (chrome) https://developer.chrome.com/blog/timer-throttling-in-chrome-88
if (timeout < 4) {
const channel = new MessageChannel();
channel.port1.onmessage = () => callback();
channel.port2.postMessage("");
} else {
setTimeout(callback, timeout);
}
}

View File

@ -1,21 +0,0 @@
import * as chai from "chai";
import { scheduleCallback } from "../../scheduler";
describe("scheduleCallback", () => {
// Note: This test requires `--exit` flag to be set for mocha
// to avoid hanging the process
// see: https://github.com/facebook/react/issues/26608
it("should call the callback immediately if timeout is 0", () => {
const start = Date.now();
scheduleCallback(() => {
chai.assert.isAtMost(Date.now() - start, 4);
});
});
it("should call the callback after the given timeout", () => {
const start = Date.now();
scheduleCallback(() => {
chai.assert.isAtLeast(Date.now() - start, 10);
}, 10);
});
});

View File

@ -322,7 +322,6 @@ export interface API {
runPythonInternal_dict: any;
saveState: () => any;
restoreState: (state: any) => void;
scheduleCallback: (callback: () => void, timeout: number) => void;
package_loader: any;
importlib: any;

View File

@ -11,7 +11,7 @@ from typing import Any, TypeVar, overload
from .ffi import IN_BROWSER, create_once_callable
if IN_BROWSER:
from pyodide_js._api import scheduleCallback
from js import setTimeout
T = TypeVar("T")
S = TypeVar("S")
@ -343,10 +343,7 @@ class WebLoop(asyncio.AbstractEventLoop):
else:
raise
scheduleCallback(
create_once_callable(run_handle, _may_syncify=True), delay * 1000
)
setTimeout(create_once_callable(run_handle, _may_syncify=True), delay * 1000)
return h
def _decrement_in_progress(self, *args):

View File

@ -497,20 +497,3 @@ async def test_inprogress(selenium):
loop._no_in_progress_handler = None
loop._keyboard_interrupt_handler = None
loop._system_exit_handler = None
@run_in_pyodide
async def test_zero_timeout(selenium):
import asyncio
import time
now = time.time()
for _ in range(1000):
await asyncio.sleep(0)
done = time.time()
elapsed = done - now
# Very rough check, we hope it's less than 4s (1000 * 4ms [setTimeout delay in most browsers])
assert elapsed < 4, f"elapsed: {elapsed}s"