-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[shared storage] Implement batchUpdate() for Window and SharedStorage…
…Worklet context This allows developers to perform multiple Shared Storage operations atomically within a single lock, as part of the Web Lock integration proposal: - WICG/shared-storage#199 - WICG/shared-storage#205 How: - Add `batchUpdate(methods, options)` to the `SharedStorage` interface. - Hooks up the `batchUpdate()` method to the `SharedStorageLockManager::SharedStorageBatchUpdate()` API in the browser process. Bug: 373899210 Fuchsia-Binary-Size: Size increase is unavoidable. Change-Id: I0e1b355e3b3d28518396ae4333afe21e6d02e858 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6069087 Reviewed-by: Ayu Ishii <ayui@chromium.org> Commit-Queue: Yao Xiao <yaoxia@chromium.org> Cr-Commit-Position: refs/heads/main@{#1391933}
- Loading branch information
1 parent
79ce401
commit b576b4d
Showing
4 changed files
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
shared-storage/web-locks-window-batch-update.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<!doctype html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/shared-storage/resources/util.js"></script> | ||
<script src="/fenced-frame/resources/utils.js"></script> | ||
|
||
<body> | ||
<script> | ||
'use strict'; | ||
|
||
promise_test(async t => { | ||
let worklet = await sharedStorage.createWorklet('resources/simple-module.js'); | ||
|
||
const ancestor_key = token(); | ||
let url0 = generateURL("/shared-storage/resources/frame0.html", | ||
[ancestor_key]); | ||
let url1 = generateURL("/shared-storage/resources/frame1.html", | ||
[ancestor_key]); | ||
|
||
// Invoke `selectURL()` to perform the following steps: | ||
// 1. Acquires the lock. | ||
// 2. Reads the current value at the given key. | ||
// 3. Waits for 500ms. | ||
// 4. Sets the shared storage value to the read value appended with the given letter. | ||
// 5. Releases the lock. | ||
// | ||
// After 100ms, invoke `sharedStorage.batchUpdate()` that: | ||
// - Acquires the same named lock. | ||
// - Executes two `append` methods, each appending the same letter. | ||
// | ||
// Expected behavior: After both of them finish, the value at the given key | ||
// should contain the letter repeated three times. | ||
// | ||
// This demonstrates that: | ||
// 1. The `withLock` option is effective, preventing the `batchUpdate()` | ||
// method interfering with the "get and set" operation. If the lock were not | ||
// used, the final value would likely be a single letter. | ||
// 2. `batchUpdate()` correctly executes all `append` methods within the | ||
// batch. | ||
// | ||
// Note: This test remains valid even if the `batchUpdate()` call happens | ||
// outside the critical section protected by the lock within the worklet. The | ||
// test effectively demonstrates mutual exclusion as long as there's a | ||
// reasonable chance for `batchUpdate()` to occur while the worklet is still | ||
// running. | ||
let select_url_result = await worklet.selectURL( | ||
"get-wait-set-within-lock", | ||
[{url: url0}, {url: url1}], | ||
{data: {'key': 'key', | ||
'lock_name': 'lock1', | ||
'append_letter': 'a'}, | ||
resolveToConfig: true}); | ||
|
||
// Busy wait for 100ms. | ||
const startWaitTime = Date.now(); | ||
while (Date.now() - startWaitTime < 100) {} | ||
|
||
sharedStorage.batchUpdate([ | ||
new SharedStorageAppendMethod('key', 'a'), | ||
new SharedStorageAppendMethod('key', 'a') | ||
], {withLock: 'lock1'}); | ||
|
||
attachFencedFrame(select_url_result, 'opaque-ads'); | ||
const result = await nextValueFromServer(ancestor_key); | ||
assert_equals(result, "frame1_loaded"); | ||
|
||
await verifyKeyValueForOrigin('key', 'aaa', location.origin); | ||
|
||
await deleteKeyForOrigin('key', location.origin); | ||
}, 'Test for batchUpdate() with a batch lock in a Window context'); | ||
|
||
</script> | ||
</body> |
85 changes: 85 additions & 0 deletions
85
shared-storage/web-locks-worklet-batch-update.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<!doctype html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/shared-storage/resources/util.js"></script> | ||
<script src="/fenced-frame/resources/utils.js"></script> | ||
|
||
<body> | ||
<script> | ||
'use strict'; | ||
|
||
promise_test(async t => { | ||
let worklet1 = await sharedStorage.createWorklet('resources/simple-module.js'); | ||
let worklet2 = await sharedStorage.createWorklet('resources/simple-module.js'); | ||
|
||
const ancestor_key1 = token(); | ||
let url1_0 = generateURL("/shared-storage/resources/frame0.html", | ||
[ancestor_key1]); | ||
let url1_1 = generateURL("/shared-storage/resources/frame1.html", | ||
[ancestor_key1]); | ||
|
||
const ancestor_key2 = token(); | ||
let url2_0 = generateURL("/shared-storage/resources/frame0.html", | ||
[ancestor_key2]); | ||
let url2_1 = generateURL("/shared-storage/resources/frame1.html", | ||
[ancestor_key2]); | ||
|
||
// Invoke `selectURL()` to perform the following steps: | ||
// 1. Acquires the lock. | ||
// 2. Reads the current value at the given key. | ||
// 3. Waits for 500ms. | ||
// 4. Sets the shared storage value to the read value appended with the given letter. | ||
// 5. Releases the lock. | ||
// | ||
// In parallel, invoke another `selectURL()`, which subsequently invokes | ||
// `sharedStorage.batchUpdate()` that: | ||
// - Acquires the same named lock. | ||
// - Executes two `append` methods, each appending the same letter. | ||
// | ||
// Expected behavior: After both of them finish, the value at the given key | ||
// should contain the letter repeated three times. | ||
// | ||
// This demonstrates that: | ||
// 1. The `withLock` option is effective, preventing the `batchUpdate()` | ||
// method interfering with the "get and set" operation. If the lock were not | ||
// used, the final value would likely be a single letter. | ||
// 2. `batchUpdate()` correctly executes all `append` methods within the | ||
// batch. | ||
// | ||
// Note: This test remains valid even if the `batchUpdate()` call happens | ||
// outside the critical section protected by the lock within the worklet. The | ||
// test effectively demonstrates mutual exclusion as long as there's a | ||
// reasonable chance for `batchUpdate()` to occur while the worklet is still | ||
// running. | ||
let select_url_result1 = await worklet1.selectURL( | ||
"get-wait-set-within-lock", | ||
[{url: url1_0}, {url: url1_1}], | ||
{data: {'key': 'key', | ||
'lock_name': 'lock1', | ||
'append_letter': 'a'}, | ||
resolveToConfig: true}); | ||
|
||
let select_url_result2 = await worklet2.selectURL( | ||
"batch-update-with-two-append-methods-with-batch-lock-option", | ||
[{url: url2_0}, {url: url2_1}], | ||
{data: {'key': 'key', | ||
'lock_name': 'lock1', | ||
'append_letter': 'a'}, | ||
resolveToConfig: true}); | ||
|
||
attachFencedFrame(select_url_result1, 'opaque-ads'); | ||
const result1 = await nextValueFromServer(ancestor_key1); | ||
assert_equals(result1, "frame1_loaded"); | ||
|
||
attachFencedFrame(select_url_result2, 'opaque-ads'); | ||
const result2 = await nextValueFromServer(ancestor_key2); | ||
assert_equals(result2, "frame1_loaded"); | ||
|
||
await verifyKeyValueForOrigin('key', 'aaa', location.origin); | ||
|
||
await deleteKeyForOrigin('key', location.origin); | ||
}, 'Test for batchUpdate() with a batch lock in a SharedStorageWorklet context'); | ||
|
||
</script> | ||
</body> |