1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00

feat(cli/ops): add the sleep_sync op (#7974)

This commit is contained in:
William Perron 2020-10-15 21:06:31 -04:00 committed by GitHub
parent bbe4474d39
commit 943b0980c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 0 deletions

View file

@ -1312,6 +1312,17 @@ declare namespace Deno {
atime: number | Date, atime: number | Date,
mtime: number | Date, mtime: number | Date,
): Promise<void>; ): Promise<void>;
/** *UNSTABLE**: new API, yet to be vetted.
*
* SleepSync puts the main thread to sleep synchronously for a given amount of
* time in milliseconds.
*
* ```ts
* Deno.sleepSync(10);
* ```
*/
export function sleepSync(millis: number): Promise<void>;
} }
declare function fetch( declare function fetch(

View file

@ -25,6 +25,7 @@ use std::cell::RefCell;
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use std::time::Instant; use std::time::Instant;
@ -77,6 +78,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) {
super::reg_json_sync(rt, "op_global_timer_start", op_global_timer_start); super::reg_json_sync(rt, "op_global_timer_start", op_global_timer_start);
super::reg_json_async(rt, "op_global_timer", op_global_timer); super::reg_json_async(rt, "op_global_timer", op_global_timer);
super::reg_json_sync(rt, "op_now", op_now); super::reg_json_sync(rt, "op_now", op_now);
super::reg_json_sync(rt, "op_sleep_sync", op_sleep_sync);
} }
fn op_global_timer_stop( fn op_global_timer_stop(
@ -157,3 +159,19 @@ fn op_now(
"subsecNanos": subsec_nanos, "subsecNanos": subsec_nanos,
})) }))
} }
#[derive(Deserialize)]
struct SleepArgs {
millis: u64,
}
fn op_sleep_sync(
state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, AnyError> {
super::check_unstable(state, "Deno.sleepSync");
let args: SleepArgs = serde_json::from_value(args)?;
sleep(Duration::from_millis(args.millis));
Ok(json!({}))
}

View file

@ -20,6 +20,10 @@
return core.jsonOpSync("op_now"); return core.jsonOpSync("op_now");
} }
function sleepSync(millis = 0) {
return core.jsonOpSync("op_sleep_sync", { millis });
}
// Derived from https://github.com/vadimg/js_bintrees. MIT Licensed. // Derived from https://github.com/vadimg/js_bintrees. MIT Licensed.
class RBNode { class RBNode {
@ -545,5 +549,6 @@
opStopGlobalTimer, opStopGlobalTimer,
opStartGlobalTimer, opStartGlobalTimer,
opNow, opNow,
sleepSync,
}; };
})(this); })(this);

View file

@ -80,6 +80,7 @@ __bootstrap.denoNs = {
listen: __bootstrap.net.listen, listen: __bootstrap.net.listen,
connectTls: __bootstrap.tls.connectTls, connectTls: __bootstrap.tls.connectTls,
listenTls: __bootstrap.tls.listenTls, listenTls: __bootstrap.tls.listenTls,
sleepSync: __bootstrap.timers.sleepSync,
}; };
__bootstrap.denoNsUnstable = { __bootstrap.denoNsUnstable = {

View file

@ -380,3 +380,55 @@ unitTest(async function timerIgnoresDateOverride(): Promise<void> {
} }
assertEquals(hasThrown, 1); assertEquals(hasThrown, 1);
}); });
unitTest({ perms: { hrtime: true } }, function sleepSync(): void {
const start = performance.now();
Deno.sleepSync(10);
const after = performance.now();
assert(after - start >= 10);
});
unitTest(
{ perms: { hrtime: true } },
async function sleepSyncShorterPromise(): Promise<void> {
const perf = performance;
const short = 5;
const long = 10;
const start = perf.now();
const p = sleepAsync(short).then(() => {
const after = perf.now();
// pending promises should resolve after the main thread comes out of sleep
assert(after - start >= long);
});
Deno.sleepSync(long);
await p;
},
);
unitTest(
{ perms: { hrtime: true } },
async function sleepSyncLongerPromise(): Promise<void> {
const perf = performance;
const short = 5;
const long = 10;
const start = perf.now();
const p = sleepAsync(long).then(() => {
const after = perf.now();
// sleeping for less than the duration of a promise should have no impact
// on the resolution of that promise
assert(after - start >= long);
});
Deno.sleepSync(short);
await p;
},
);
function sleepAsync(delay: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(() => resolve(), delay);
});
}