You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec.bs
+55-42Lines changed: 55 additions & 42 deletions
Original file line number
Diff line number
Diff line change
@@ -1415,6 +1415,50 @@ The Shared Storage API will integrate into the [=Storage Model|Storage API=] as
1415
1415
1. Return the result of running [=shared storage database/store an entry in the database=] with |queue|, |databaseMap|, |environment|, |key|, and |value|.
1416
1416
</div>
1417
1417
1418
+
<div algorithm>
1419
+
1420
+
To <dfn for="shared storage database">batch update entries in the database</dfn>, given a [=shared storage database/shared storage database queue=] |queue|, a [=storage proxy map=] |databaseMap|, an [=environment settings object=] |environment|, and a [=list=] of {{SharedStorageModifierMethod}} |methods|, run the following steps on |queue|:
1421
+
1422
+
1. Let |originalDatabaseMap| be |databaseMap|.
1423
+
1424
+
1. Let |innerMethodFailed| be false.
1425
+
1. For each |method| in |methods|:
1426
+
1. If |method| is a {{SharedStorageSetMethod}}:
1427
+
1. Let |key| be |method|'s [=SharedStorageSetMethod/key=].
1428
+
1. Let |value| be |method|'s [=SharedStorageSetMethod/value=].
1429
+
1. Let |ignoreIfPresent| be |method|'s [=SharedStorageSetMethod/ignore if present=].
1430
+
1. Let |result| be the result of running [=shared storage database/set an entry in the database=] with |queue|, |databaseMap|, |environment|, |key|, |value|, and |ignoreIfPresent|.
1431
+
1. If |result| is false:
1432
+
1. Set |innerMethodFailed| to true.
1433
+
1. Break.
1434
+
1. Else if |method| is a {{SharedStorageAppendMethod}}:
1435
+
1. Let |key| be |method|'s [=SharedStorageAppendMethod/key=].
1436
+
1. Let |value| be |method|'s [=SharedStorageAppendMethod/value=].
1437
+
1. Let |result| be the result of running [=shared storage database/append an entry in the database=] with |queue|, |databaseMap|, |environment|, |key|, and |value|.
1438
+
1. If |result| is false:
1439
+
1. Set |innerMethodFailed| to true.
1440
+
1. Break.
1441
+
1. Else if |method| is a {{SharedStorageDeleteMethod}}:
1442
+
1. Let |key| be |method|'s [=SharedStorageDeleteMethod/key=].
1443
+
1. Let |result| be the result of running [=shared storage database/delete an entry from the database=] with |queue|, |databaseMap|, |environment|, and |key|.
1444
+
1. If |result| is false:
1445
+
1. Set |innerMethodFailed| to true.
1446
+
1. Break.
1447
+
1. Else:
1448
+
1. [=Assert=]: |method| is a {{SharedStorageClearMethod}}.
1449
+
1. Let |result| be the result of running [=shared storage database/clear all entries in the database=] with |queue|, |databaseMap|, and |environment|.
1450
+
1. If |result| is false:
1451
+
1. Set |innerMethodFailed| to true.
1452
+
1. Break.
1453
+
1. If |innerMethodFailed|:
1454
+
1. Set |databaseMap| to |originalDatabaseMap|.
1455
+
1. Return false.
1456
+
1. Return true.
1457
+
</div>
1458
+
1459
+
<div class="note">
1460
+
This algorithm uses a naive rollback mechanism. For production environments, consider more efficient techniques that avoid full database copies.
1461
+
</div>
1418
1462
1419
1463
Extension to the {{Window}} interface {#window-extension}
@@ -1712,57 +1756,26 @@ Note: The [=determine if a navigable has fully revoked network=] algorithm ensur
1712
1756
1. If the result of running [=SharedStorageWorkletGlobalScope/check whether addModule is finished=] for {{SharedStorage}}'s associated {{SharedStorageWorkletGlobalScope}} is false, return a [=promise rejected=] with a {{TypeError}}.
1713
1757
1. If |context| is null, return a [=promise rejected=] with a {{TypeError}}.
1714
1758
1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}.
1759
+
1. For each |method| in |methods|:
1760
+
1. If |method|["{{SharedStorageModifierMethodOptions/withLock}}"][=map/exists=]:
1761
+
1. Return a [=promise rejected=] with a {{TypeError}}.
1762
+
1763
+
Note: `batchUpdate()` executes as a transactional operation. To avoid potential deadlocks from finer-grained locking, inner methods within `batchUpdate()` cannot utilize the `withLock` option. Instead of ignoring this option, an error is thrown to enforce the restriction and prevent misuse.
1715
1764
1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=].
1716
1765
1. Let |databaseMap| be the result of running [=obtain a shared storage bottle map=] given |environment| and |environment|'s [=environment settings object/origin=].
1717
1766
1. If |databaseMap| is failure, then return a [=promise rejected=] with a {{TypeError}}.
1718
-
1. Let |unfinishedUpdatesCount| be |methods|'s [=list/size=].
1719
-
1. Let |hasFailure| be false.
1720
1767
1. Let |onLockGrantedCallback| be an algorithm to perform the following steps:
1721
-
1. For each |method| in |methods|:
1722
-
1. Let |methodResultPromise| be a new [=promise=].
1723
-
1. If |method| is a {{SharedStorageSetMethod}}:
1724
-
1. Let |key| be |method|'s [=SharedStorageSetMethod/key=].
1725
-
1. Let |value| be |method|'s [=SharedStorageSetMethod/value=].
1726
-
1. Let |methodOptions| be a new {{SharedStorageSetMethodOptions}}.
1727
-
1. Set |methodOptions|["{{SharedStorageSetMethodOptions/ignoreIfPresent}}"] to |method|'s [=SharedStorageSetMethod/ignore if present=].
1728
-
1. If |method|'s [=SharedStorageModifierMethod/with lock=] is not null, set |methodOptions|["{{SharedStorageModifierMethodOptions/withLock}}"] to |method|'s [=SharedStorageModifierMethod/with lock=].
1729
-
1. Set |methodResultPromise| to the result of invoking {{SharedStorage/set()|set}}(|key|, |value|, |methodOptions|).
1730
-
1. Else if |method| is a {{SharedStorageAppendMethod}}:
1731
-
1. Let |key| be |method|'s [=SharedStorageAppendMethod/key=].
1732
-
1. Let |value| be |method|'s [=SharedStorageAppendMethod/value=].
1733
-
1. Let |methodOptions| be a new {{SharedStorageModifierMethodOptions}}.
1734
-
1. If |method|'s [=SharedStorageModifierMethod/with lock=] is not null, set |methodOptions|["{{SharedStorageModifierMethodOptions/withLock}}"] to |method|'s [=SharedStorageModifierMethod/with lock=].
1735
-
1. Set |methodResultPromise| to the result of invoking {{SharedStorage/append()|append}}(|key|, |value|, |methodOptions|).
1736
-
1. Else if |method| is a {{SharedStorageDeleteMethod}}:
1737
-
1. Let |key| be |method|'s [=SharedStorageDeleteMethod/key=].
1738
-
1. Let |methodOptions| be a new {{SharedStorageModifierMethodOptions}}.
1739
-
1. If |method|'s [=SharedStorageModifierMethod/with lock=] is not null, set |methodOptions|["{{SharedStorageModifierMethodOptions/withLock}}"] to |method|'s [=SharedStorageModifierMethod/with lock=].
1740
-
1. Set |methodResultPromise| to the result of invoking {{SharedStorage/delete()|delete}}(|key|, |methodOptions|).
1741
-
1. Else:
1742
-
1. [=Assert=]: |method| is a {{SharedStorageClearMethod}}.
1743
-
1. Let |methodOptions| be a new {{SharedStorageModifierMethodOptions}}.
1744
-
1. If |method|'s [=SharedStorageModifierMethod/with lock=] is not null, set |methodOptions|["{{SharedStorageModifierMethodOptions/withLock}}"] to |method|'s [=SharedStorageModifierMethod/with lock=].
1745
-
1. Set |methodResultPromise| to the result of invoking {{SharedStorage/clear()|clear}}(|methodOptions|).
1746
-
1. [=Upon fulfillment=] of |methodResultPromise|:
1747
-
1. Decrement |unfinishedUpdatesCount| by 1.
1748
-
1. If |unfinishedUpdatesCount| is 0, run [=finish a batch update=] given |promise| and |hasFailure|.
1749
-
1. [=Upon rejection=] of |methodResultPromise|:
1750
-
1. Decrement |unfinishedUpdatesCount| by 1.
1751
-
1. Set |hasFailure| to true.
1752
-
1. If |unfinishedUpdatesCount| is 0, run [=finish a batch update=] given |promise| and |hasFailure|.
1753
-
1. If |unfinishedUpdatesCount| is 0, run [=finish a batch update=] given |promise| and |hasFailure|.
1768
+
1. [=Enqueue the following steps=] on |queue|:
1769
+
1. Let |result| be the result of running [=shared storage database/batch update entries in the database=] with |queue|, |databaseMap|, |environment|, and |methods|.
1770
+
1. If |result| is false and if |globalObject| is a {{SharedStorageWorkletGlobalScope}}:
1771
+
1. [=Queue a global task=] on the [=DOM manipulation task source=], given |realm|'s [=global object=], to [=reject=] |promise| with a {{TypeError}}.
1772
+
1. Abort these steps.
1773
+
1. [=Queue a global task=] on the [=DOM manipulation task source=], given |realm|'s [=global object=], to [=resolve=] |promise| with undefined.
1754
1774
1. If |options|["{{SharedStorageModifierMethodOptions/withLock}}"][=map/exists=], run [=handle callback within a shared storage lock=] given |environment|'s [=environment settings object/origin=], |options|["{{SharedStorageModifierMethodOptions/withLock}}"], |onLockGrantedCallback|.
1755
1775
1. Else, run |onLockGrantedCallback|.
1756
1776
1. Return |promise|.
1757
1777
</div>
1758
1778
1759
-
<div algorithm>
1760
-
To <dfn>finish a batch update</dfn>, given a [=promise=] |promise| and a [=/boolean=] |hasFailure|, perform the following steps:
1761
-
1762
-
1. If |hasFailure| is true, [=reject=] |promise| with a {{TypeError}}.
0 commit comments