antfu-collective / vitesse-webext

⚡️ WebExtension Vite Starter Template
MIT License
2.92k stars 225 forks source link

Reactive storage infinite loop caused by race conditions #162

Open flytaly opened 9 months ago

flytaly commented 9 months ago

Describe the bug

The reactive storage introduced in #157 could lead to an infinite loop if properties of an object were changed in rapid succession inside asynchronous code. If this happens in a background script, it can make the browser unusable.

Example (full reproduction also included):

 async function fn() {
  storageData.value.timestamp = Date.now()
  await Promise.resolve()
  storageData.value.timestamp = Date.now()
}

image

Reproduction

https://github.com/flytaly/vitesse-webext-infinite-loop/commit/3d93d8fd4f7c6f49615e8c433a07932cbd1bad70

System Info

System:
    OS: Linux 6.7 Arch Linux
    CPU: (12) x64 Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz
    Memory: 3.84 GB / 15.47 GB
    Container: Yes
    Shell: 5.2.26 - /bin/bash
  Binaries:
    Node: 21.6.1 - /run/user/1000/fnm_multishells/76639_1708848850539/bin/node
    npm: 10.4.0 - /run/user/1000/fnm_multishells/76639_1708848850539/bin/npm
    pnpm: 8.3.1 - /run/user/1000/fnm_multishells/76639_1708848850539/bin/pnpm
    bun: 1.0.3 - ~/.bun/bin/bun

Used Package Manager

pnpm

Validations

flytaly commented 9 months ago

Ok, I have found a way to handle this by using the throttleFilter (or debounceFilter) from vueuse.

useWebExtensionStorage(key, initial, { eventFilter: throttleFilter(200) })
iplanwebsites commented 5 months ago

Can confirm this bug is present occasionally and it does freeze Chrome entirely. What would be a good default setting to prevent these?