diff options
| author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2021-11-25 19:49:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-25 19:49:09 +0100 |
| commit | f3c0f0565bbf43b4cc31979b05e729d4f4a1538f (patch) | |
| tree | 6554dfdecd89e076166531b91824d6750d5b76e0 /core/01_core.js | |
| parent | 2853e3760471560c1812b46007e1a525966b1365 (diff) | |
feat(core): Add ability to "ref" and "unref" pending ops (#12889)
This commit adds an ability to "ref" or "unref" pending ops.
Up to this point Deno had a notion of "async ops" and "unref async ops";
the former keep event loop alive, while the latter do not block event loop
from finishing. It was not possible to change between op types after
dispatching, one had to decide which type to use before dispatch.
Instead of storing ops in two separate "FuturesUnordered" collections,
now ops are stored in a single collection, with supplemental "HashSet"
storing ids of promises that were "unrefed".
Two APIs were added to "Deno.core":
"Deno.core.refOp(promiseId)" which allows to mark promise id
to be "refed" and keep event loop alive (the default behavior)
"Deno.core.unrefOp(promiseId)" which allows to mark promise
id as "unrefed" which won't block event loop from exiting
Diffstat (limited to 'core/01_core.js')
| -rw-r--r-- | core/01_core.js | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/core/01_core.js b/core/01_core.js index 75bfc884f..c3fd7cf9d 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -23,6 +23,7 @@ MapPrototypeSet, PromisePrototypeThen, ObjectAssign, + SymbolFor, } = window.__bootstrap.primordials; // Available on start due to bindings. @@ -43,6 +44,9 @@ const RING_SIZE = 4 * 1024; const NO_PROMISE = null; // Alias to null is faster than plain nulls const promiseRing = ArrayPrototypeFill(new Array(RING_SIZE), NO_PROMISE); + // TODO(bartlomieju): it future use `v8::Private` so it's not visible + // to users. Currently missing bindings. + const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId"); function setPromise(promiseId) { const idx = promiseId % RING_SIZE; @@ -135,7 +139,10 @@ const maybeError = opcallAsync(opsCache[opName], promiseId, arg1, arg2); // Handle sync error (e.g: error parsing args) if (maybeError) return unwrapOpResult(maybeError); - return PromisePrototypeThen(setPromise(promiseId), unwrapOpResult); + const p = PromisePrototypeThen(setPromise(promiseId), unwrapOpResult); + // Save the id on the promise so it can later be ref'ed or unref'ed + p[promiseIdSymbol] = promiseId; + return p; } function opSync(opName, arg1 = null, arg2 = null) { |
