mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
worker: add web locks api
PR-URL: https://github.com/nodejs/node/pull/58666 Fixes: https://github.com/nodejs/node/pull/36502 Refs: https://w3c.github.io/web-locks Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
0629a175c0
commit
062e8b5a74
70 changed files with 5030 additions and 0 deletions
|
@ -768,6 +768,55 @@ consisting of the runtime name and major version number.
|
|||
console.log(`The user-agent is ${navigator.userAgent}`); // Prints "Node.js/21"
|
||||
```
|
||||
|
||||
### `navigator.locks`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
The `navigator.locks` read-only property returns a [`LockManager`][] instance that
|
||||
can be used to coordinate access to resources that may be shared across multiple
|
||||
threads within the same process. This global implementation matches the semantics
|
||||
of the [browser `LockManager`][] API.
|
||||
|
||||
```mjs
|
||||
// Request an exclusive lock
|
||||
await navigator.locks.request('my_resource', async (lock) => {
|
||||
// The lock has been acquired.
|
||||
console.log(`Lock acquired: ${lock.name}`);
|
||||
// Lock is automatically released when the function returns
|
||||
});
|
||||
|
||||
// Request a shared lock
|
||||
await navigator.locks.request('shared_resource', { mode: 'shared' }, async (lock) => {
|
||||
// Multiple shared locks can be held simultaneously
|
||||
console.log(`Shared lock acquired: ${lock.name}`);
|
||||
});
|
||||
```
|
||||
|
||||
```cjs
|
||||
// Request an exclusive lock
|
||||
navigator.locks.request('my_resource', async (lock) => {
|
||||
// The lock has been acquired.
|
||||
console.log(`Lock acquired: ${lock.name}`);
|
||||
// Lock is automatically released when the function returns
|
||||
}).then(() => {
|
||||
console.log('Lock released');
|
||||
});
|
||||
|
||||
// Request a shared lock
|
||||
navigator.locks.request('shared_resource', { mode: 'shared' }, async (lock) => {
|
||||
// Multiple shared locks can be held simultaneously
|
||||
console.log(`Shared lock acquired: ${lock.name}`);
|
||||
}).then(() => {
|
||||
console.log('Shared lock released');
|
||||
});
|
||||
```
|
||||
|
||||
See [`worker.locks`][] for detailed API documentation.
|
||||
|
||||
## Class: `PerformanceEntry`
|
||||
|
||||
<!-- YAML
|
||||
|
@ -1263,6 +1312,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
|
|||
[`CountQueuingStrategy`]: webstreams.md#class-countqueuingstrategy
|
||||
[`DecompressionStream`]: webstreams.md#class-decompressionstream
|
||||
[`EventTarget` and `Event` API]: events.md#eventtarget-and-event-api
|
||||
[`LockManager`]: worker_threads.md#class-lockmanager
|
||||
[`MessageChannel`]: worker_threads.md#class-messagechannel
|
||||
[`MessagePort`]: worker_threads.md#class-messageport
|
||||
[`PerformanceEntry`]: perf_hooks.md#class-performanceentry
|
||||
|
@ -1313,6 +1363,8 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
|
|||
[`setTimeout`]: timers.md#settimeoutcallback-delay-args
|
||||
[`structuredClone`]: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
|
||||
[`window.navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
|
||||
[`worker.locks`]: worker_threads.md#workerlocks
|
||||
[browser `LockManager`]: https://developer.mozilla.org/en-US/docs/Web/API/LockManager
|
||||
[buffer section]: buffer.md
|
||||
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
|
||||
[timers]: timers.md
|
||||
|
|
|
@ -755,6 +755,153 @@ if (isMainThread) {
|
|||
}
|
||||
```
|
||||
|
||||
## `worker.locks`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
* {LockManager}
|
||||
|
||||
An instance of a [`LockManager`][LockManager] that can be used to coordinate
|
||||
access to resources that may be shared across multiple threads within the same
|
||||
process. The API mirrors the semantics of the
|
||||
[browser `LockManager`][]
|
||||
|
||||
### Class: `Lock`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
The `Lock` interface provides information about a lock that has been granted via
|
||||
[`locks.request()`][locks.request()]
|
||||
|
||||
#### `lock.name`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* {string}
|
||||
|
||||
The name of the lock.
|
||||
|
||||
#### `lock.mode`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* {string}
|
||||
|
||||
The mode of the lock. Either `shared` or `exclusive`.
|
||||
|
||||
### Class: `LockManager`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
The `LockManager` interface provides methods for requesting and introspecting
|
||||
locks. To obtain a `LockManager` instance use
|
||||
|
||||
```mjs
|
||||
import { locks } from 'node:worker_threads';
|
||||
```
|
||||
|
||||
```cjs
|
||||
'use strict';
|
||||
|
||||
const { locks } = require('node:worker_threads');
|
||||
```
|
||||
|
||||
This implementation matches the [browser `LockManager`][] API.
|
||||
|
||||
#### `locks.request(name[, options], callback)`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* `name` {string}
|
||||
* `options` {Object}
|
||||
* `mode` {string} Either `'exclusive'` or `'shared'`. **Default:** `'exclusive'`.
|
||||
* `ifAvailable` {boolean} If `true`, the request will only be granted if the
|
||||
lock is not already held. If it cannot be granted, `callback` will be
|
||||
invoked with `null` instead of a `Lock` instance. **Default:** `false`.
|
||||
* `steal` {boolean} If `true`, any existing locks with the same name are
|
||||
released and the request is granted immediately, pre-empting any queued
|
||||
requests. **Default:** `false`.
|
||||
* `signal` {AbortSignal} that can be used to abort a
|
||||
pending (but not yet granted) lock request.
|
||||
* `callback` {Function} Invoked once the lock is granted (or immediately with
|
||||
`null` if `ifAvailable` is `true` and the lock is unavailable). The lock is
|
||||
released automatically when the function returns, or—if the function returns
|
||||
a promise—when that promise settles.
|
||||
* Returns: {Promise} Resolves once the lock has been released.
|
||||
|
||||
```mjs
|
||||
import { locks } from 'node:worker_threads';
|
||||
|
||||
await locks.request('my_resource', async (lock) => {
|
||||
// The lock has been acquired.
|
||||
});
|
||||
// The lock has been released here.
|
||||
```
|
||||
|
||||
```cjs
|
||||
'use strict';
|
||||
|
||||
const { locks } = require('node:worker_threads');
|
||||
|
||||
locks.request('my_resource', async (lock) => {
|
||||
// The lock has been acquired.
|
||||
}).then(() => {
|
||||
// The lock has been released here.
|
||||
});
|
||||
```
|
||||
|
||||
#### `locks.query()`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* Returns: {Promise}
|
||||
|
||||
Resolves with a `LockManagerSnapshot` describing the currently held and pending
|
||||
locks for the current process.
|
||||
|
||||
```mjs
|
||||
import { locks } from 'node:worker_threads';
|
||||
|
||||
const snapshot = await locks.query();
|
||||
for (const lock of snapshot.held) {
|
||||
console.log(`held lock: name ${lock.name}, mode ${lock.mode}`);
|
||||
}
|
||||
for (const pending of snapshot.pending) {
|
||||
console.log(`pending lock: name ${pending.name}, mode ${pending.mode}`);
|
||||
}
|
||||
```
|
||||
|
||||
```cjs
|
||||
'use strict';
|
||||
|
||||
const { locks } = require('node:worker_threads');
|
||||
|
||||
locks.query().then((snapshot) => {
|
||||
for (const lock of snapshot.held) {
|
||||
console.log(`held lock: name ${lock.name}, mode ${lock.mode}`);
|
||||
}
|
||||
for (const pending of snapshot.pending) {
|
||||
console.log(`pending lock: name ${pending.name}, mode ${pending.mode}`);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Class: `BroadcastChannel extends EventTarget`
|
||||
|
||||
<!-- YAML
|
||||
|
@ -1937,6 +2084,7 @@ thread spawned will spawn another until the application crashes.
|
|||
[Addons worker support]: addons.md#worker-support
|
||||
[ECMAScript module loader]: esm.md#data-imports
|
||||
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
[LockManager]: #class-lockmanager
|
||||
[Signals events]: process.md#signal-events
|
||||
[Web Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
|
||||
[`'close'` event]: #event-close
|
||||
|
@ -1992,7 +2140,9 @@ thread spawned will spawn another until the application crashes.
|
|||
[`worker.terminate()`]: #workerterminate
|
||||
[`worker.threadId`]: #workerthreadid_1
|
||||
[async-resource-worker-pool]: async_context.md#using-asyncresource-for-a-worker-thread-pool
|
||||
[browser `LockManager`]: https://developer.mozilla.org/en-US/docs/Web/API/LockManager
|
||||
[browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
[child processes]: child_process.md
|
||||
[contextified]: vm.md#what-does-it-mean-to-contextify-an-object
|
||||
[locks.request()]: #locksrequestname-options-callback
|
||||
[v8.serdes]: v8.md#serialization-api
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue