-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A simple globally available store of data per-registration #1331
Comments
Can you give some more details on the use case? As in, what would the data be? When would it be set? When would it be used? If the data was associated with the registration it would need to be immutable, since multiple threads have access to the registration. Unless the access was async of course, but then you may as well use async key val. I guess any proposal like this should be vs async key val. |
Ah.. right. The notification's data attribute is readonly and not concurrently accessed from multiple threads. For service workers, we're queuing the (lifecycle) jobs that can concurrently access a registration. @jakearchibald, what's "async key val" here? |
FWIW, if we really need this, we would be able to run the getter and setter in https://html.spec.whatwg.org/#parallel-queue? |
I think Jake's (and at least mine) question is: if this has to be an asynchronous API anyway, what's the benefit of having something SW specific over just using a "normal" storage API (i.e. cache storage, IDB or some not-yet-existing async localstorage style API)? |
Opening IDB is frequently slow and IDB's API is promise-hostile. Neither
are great arguments, but taken together it creates a real hurdle for
storing global configuration data (e.g., SW "timeout"; a date after which a
SW should stop handling requests and perhaps unregister itself).
…On Fri, 29 Jun 2018, 18:20 Marijn Kruisselbrink, ***@***.***> wrote:
I think Jake's (and at least mine) question is: if this has to be an
asynchronous API anyway, what's the benefit of having something SW specific
over just using a "normal" storage API (i.e. cache storage, IDB or some
not-yet-existing async localstorage style API)?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1331 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAF8M498WBiXCvTl0bJCFXi8_z4hB4Hsks5uBmHwgaJpZM4U8F_I>
.
|
Does https://github.com/domenic/async-local-storage solve these problems?
…On Fri, 29 Jun 2018, 19:20 Alex Russell, ***@***.***> wrote:
Opening IDB is frequently slow and IDB's API is promise-hostile. Neither
are great arguments, but taken together it creates a real hurdle for
storing global configuration data (e.g., SW "timeout"; a date after which a
SW should stop handling requests and perhaps unregister itself).
On Fri, 29 Jun 2018, 18:20 Marijn Kruisselbrink, ***@***.***
>
wrote:
> I think Jake's (and at least mine) question is: if this has to be an
> asynchronous API anyway, what's the benefit of having something SW
specific
> over just using a "normal" storage API (i.e. cache storage, IDB or some
> not-yet-existing async localstorage style API)?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1331 (comment)
>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AAF8M498WBiXCvTl0bJCFXi8_z4hB4Hsks5uBmHwgaJpZM4U8F_I
>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1331 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFtmsGvBcZZSr7-1tk3WTy8WByJusNwks5uBm_egaJpZM4U8F_I>
.
|
Not for global configuration data one might want to guard fetch-handling
on, e.g.; the goal here would be to avoid needing this sort of thing to be
more delayed (asynchronous) than necessary.
…On Sat, 30 Jun 2018, 08:50 Jake Archibald, ***@***.***> wrote:
Does https://github.com/domenic/async-local-storage solve these problems?
On Fri, 29 Jun 2018, 19:20 Alex Russell, ***@***.***> wrote:
> Opening IDB is frequently slow and IDB's API is promise-hostile. Neither
> are great arguments, but taken together it creates a real hurdle for
> storing global configuration data (e.g., SW "timeout"; a date after
which a
> SW should stop handling requests and perhaps unregister itself).
>
> On Fri, 29 Jun 2018, 18:20 Marijn Kruisselbrink, <
***@***.***
> >
> wrote:
>
> > I think Jake's (and at least mine) question is: if this has to be an
> > asynchronous API anyway, what's the benefit of having something SW
> specific
> > over just using a "normal" storage API (i.e. cache storage, IDB or some
> > not-yet-existing async localstorage style API)?
> >
> > —
> > You are receiving this because you authored the thread.
> > Reply to this email directly, view it on GitHub
> > <
#1331 (comment)
> >,
> > or mute the thread
> > <
>
https://github.com/notifications/unsubscribe-auth/AAF8M498WBiXCvTl0bJCFXi8_z4hB4Hsks5uBmHwgaJpZM4U8F_I
> >
> > .
> >
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#1331 (comment)
>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AAFtmsGvBcZZSr7-1tk3WTy8WByJusNwks5uBm_egaJpZM4U8F_I
>
> .
>
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1331 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAF8MyNSdSTXmPLp5-gbsRK1rWW27ykkks5uBy2-gaJpZM4U8F_I>
.
|
We've run into the exact problem for the exact use case mentioned by @slightlyoff. Another use case is storing the CSRF token, since cookies aren't available in the service worker. Side note, perhaps the expiration use-case is universal enough that we might want to introduce some sort of response header for the service worker file that dictates how long the service worker is allowed to be used? |
Forgot to mention: we ran some experiments against real traffic, which supports the idea that IndexedDB is too slow for critical path operations. IndexedDB access time was often over 1 second, and we experienced a significant amount of IndexedDB access timeouts. Would it be possible to have a read and write sync store, with the caveat that any properties that are writable from the worker are not guaranteed to be up-to-date when reading? We have experimented with a caching scheme with multiple caches, where a sync-accessed property would be very helpful for figuring out which cache to use for a certain request. Trying to request from the wrong cache is acceptable. |
This also came up in #1157. Having some small set of synchronously available data seems to be a recurring request. As an implementer, I'd posit the most important things in such an API are:
URLSearchParams is roughly an example of such an existing API that could be abused. It has a string serialization, and the size constraint could be on registration.params.toString().length. This encoding also lends itself to simple tunneling of the state from the server. |
@asutherland as a user/consumer, both your points seem good to me. On another note, does it make more sense for the store to be per-registration, or per version? Or do we need both? If someone wanted to implement an expiration date for a service worker version, I think that would make more sense as part of a per-version store. Another use-case for a small, sync store would be feature flags. This follows the same theme of "small piece of data that blocks critical path logic." |
Why do we feel that this thing will be faster than indexeddb? Depending on the design, we may be taking whatever hit per service worker wakeup, even if the data isn't needed. |
@jakearchibald I would expect a simple key-value store that has a very small size limit to be faster than IndexedDB. I believe we are appealing to the general principle of As @asutherland put it:
|
I think the more realistic competition here is the https://github.com/WICG/cookie-store API. In Firefox, Implementation-wise, in Firefox, I think we'd throw my ugly proposal on the registration. Because the reality is that what I proposed above is already available. You can do Also, a related factor that I expect weighs heavily in requesting synchronous access is that not invoking |
I agree. For instance, we have been experimenting with using
Sounds like a great start. For our needs, it would be nice to eventually have a store that is writable from the install hook of the service worker. So that we can implement a timeout/expiration date specific to each version. i.e., once a version is installed, it can only operate for a set amount of days.
Makes sense. I'm curious as to if there any cases where not invoking To be clear, I don't really care what the final solution is, as long as it provides a fast, reliable way to persist a small amount of information that can written to from the window scope and from the install step. |
I'd still like to know some use-cases. What kinds of data do developers want to store? When do they want to set it? When do they want to update it? The only example I've seen so far is from @asakusuma:
But the answer there is https://github.com/WICG/cookie-store. |
@jakearchibald some more use cases: Expiration date or timeout for a service workerGoal here is to create a safeguard against a service worker operating too long or forever. On install, the service worker records an entry in the store noting the version (string uniquely identifying the version, embedded in the script) and the current timestamp. Then, on Throttling or debouncingIn order to throttle an operation, you need to know the last time it happened. Let's say you want to implement some sort of heartbeat or need to check the server regularly for something. You could do the check on every Cache pointersConsider a single service worker that handles requests for multiple applications. You might have multiple apps on a single domain, or you might serve a different app at the exact same url, depending on network speed or locale. Or you may simply want to be able to update the app immediately without having to always use Feature flagsYou want to either run an A/B experiment, or be able to turn on/off a feature, without going through the normal install/activate cycle. There are a number of ways to implement, but there would need to be some sort of server endpoint that provided the latest feature flags. This endpoint could be called periodically (would probably need the throttle use case above) to update the flags, which would be stored in the proposed store. These flags might determine critical path behavior for The last two use cases boil down to being able to make adjustments to behavior without going through the normal install/activate phase. This is needed when you don't want to use |
F2F: There was a fairly long discussion. It boiled down to: let's wait for Convenience Storage (https://github.com/domenic/async-local-storage) and then reevaluate. |
To clarify for those not present at the meeting, "convenience storage" is whatever final name is chosen for this proposal: |
Since Convenience Storage is just a layer on top of IndexedDB, Convenience Storage won't be able to solve the latency issues. We need an API that can be on the critical path for responding to HTTP requests. So ideally should be less than 5ms. |
@asakusuma Do I remember correctly that you experienced the IDB slowness in both chrome and firefox? And that you were able to replace some IDB usage with Cache API as a key/val? This would be somewhat surprising to me since I know that IDB and Cache API are both implemented on sqlite in firefox. I would expect them to have similar performance characteristics. Perhaps the difference is that Cache API gets warmed up in the process of loading the service worker scripts themselves, so any slowness has already been experienced in the worker startup time. Then when the script hits IDB it has to warm a second database. Having a separate bug for this slow IDB behavior might be useful, though. |
Correct. However, I did not do a statistically high fidelity analysis of the IDB timeouts across browsers. I just eyeballed looking at the data and knowing our browser traffic breakdown. So I could be off. I'd like to do a more detailed experiment that can provide latency percentiles, instead of just an error count when the timeout is blown. The error count was in the seconds. I'd say that anything over 100ms is a non-starter for anything time sensitive. Over 10ms is sub-optimal. |
It's worth calling out that:
Re: IDB latency in Firefox, our implementation currently does an awkward open-close-open thing (due to mozStorage's ownership assertions interacting with Gecko's IDB threading model) that could be bad for latency due to WAL checkpointing and wasted/serialized I/O. This is among the low-hanging fruit we plan to look at. |
Something we've long punted has been the question of how to deal with volatile but infrequently changing data that is globally useful on a per-registration basis; e.g. a "kill switch deadline" for a SW version.
Thoughts about a
.data
property on registrations similar to the one we provide fornotificationclick
? I could imagine getters/setters at both registration time and later in the lifecycle, allowing services to move a lot of this sort of information out of globals.The text was updated successfully, but these errors were encountered: