-
Notifications
You must be signed in to change notification settings - Fork 12
Matching Observer creation, like IntersectionObserver #24
Comments
The second argument to observer.observe() should probably be a dict. As features creep in, using a flat list of arguments will get gross. |
What values are in the record? I see so far |
Why use a |
@bfgeek changes: {
db: <object>, // The database connection object. If null, then the change
// was from a different database connection.
transaction: <object>, // A readonly transaction over the object stores that
// this observer is listening to. This is populated when
// includeTransaction is set in the options.
records: Map<string, Array<object>> // The changes, outlined below.
} Example records map: {'objectStore1' => [{type: "add", key: IDBKeyRange.only(1), value: "val1"},
{type: "add", key: IDBKeyRange.only(2), value: "val2"},
{type: "put", key: IDBKeyRange.only(4), value: "val4"},
{type: "delete", key: IDBKeyRange.bound(5, 6, false, false)}],
'objectStore2' => [{type: "add", key: IDBKeyRange.only(1), value: "val1"},
{type: "add", key: IDBKeyRange.only(2), value: "val2"}]} @szager-chromium I think that's going to be the debate. I think we should require a database connection and a transaction, and then have the dict after that. This does two things:
I'll make it more clear that this is the intent above. |
@bfgeek for the transaction: We pretty much always want to be able to read or write to the database right before we start observing. See the examples, in order to have our UI be correct, or for us to not miss a change to the web server, or miss a change in our cache, we need to know our pre-observation state. Otherwise we can either:
We also want to build in object store filtering, so the user can't just observe all changes to all object stores by default, as this could cause a lot of performance issues as the easy & default option. Including the transaction does this. |
Is it a typo to set onlyExternal to true in the example of Server sync worker when onlyExternal means "only listen for changes from other db connections"? |
No, that makes it so that worker doesn't receive notifications for it's own changes (for example, if the webserver sends it changes). I didn't put that part in the example, I'll do that now. Instead it only receives changes from other connections, which would be real tabs or other workers. Is that confusing? What did you think it was doing? |
My bad. You have mentioned that clearly in the comment: |
oh, I just added that, it wasn't there before (sorry for the confusion). I'm glad you had that question though, it means it's a slightly confusing feature. |
Will there be a potential issue in 'Custom refresh logic' if it is requested while another 'write' transaction is ongoing? Then, there will be a timing issue to the developers that the change in the write transaction can not be listened by this observer. |
Hm, yeah I wasn't thinking about the 'completion' time of the readonly transaction, especially if it's empty. That doesn't just complete automatically because there's no requests? I was imagining the 'custom refresh' logic would do some sort of it's own transaction to read the current state. But this would definitley miss things, like you talked about. I'll update that example to use the 'transaction' feature, and have the call read from that transaction. I think that makes a lot more sense for this example, and shows off that feature. How does that sound? |
IMHO, it won't be complete because it haven't been started yet if a write transaction with overlapping scope is ongoing according to the note in IDB spec [1]. If we'd like to make the 'custom refresh' logic works while another write transaction is ongoing, the spec in IDB [1] might have to specify the rule more precisely in this specific scenario. [1] http://w3c.github.io/IndexedDB/#transaction-concept Test script of the "readonly" transaction order if there is no operation: var db;
var write_txn, read_txn;
var rq_add1, rq_add2;
var objStore;
var open_rq = indexedDB.open("testDB");
open_rq.onupgradeneeded = function(e) {
db = e.target.result;
objStore = db.createObjectStore("store");
}
open_rq.onsuccess = function(event) {
db = event.target.result;
write_txn = db.transaction("store", "readwrite");
write_txn.oncomplete = function() {
console.log("write_txn.oncomplete");
};
objStore = write_txn.objectStore("store");
rq_add1 = objStore.put({ animal: "Unicorn" }, 1);
rq_add1.onsuccess = function() {
console.log("rq_add1.oncomplete");
read_txn = db.transaction("store", "readonly");
read_txn.oncomplete = function() {
console.log("read_txn.oncomplete");
};
rq_add2 = objStore.put({ animal: "Horse" }, 2);
rq_add2.onsuccess = function() {
console.log("rq_add2.oncomplete");
}
}
} |
I see. Do you have any suggestions? I'm thinking:
|
@bevis-tseng - thanks for the note about the transaction ordering issue - I've filed https://bugs.chromium.org/p/chromium/issues/detail?id=614530 for the Blink issue. |
So, it seems to be an ordering issue in Blink implementation. Or are we still going to specify something new in IDB Spec for the transaction used by the observer, when observer in IDB is supported? If this is taken into consideration, we have to specify this carefully about identify an empty transaction for observation, because some web developer will put the operations of a transaction in the promise which makes thing more complicated to identify an empty transaction. |
It seems like there isn't any specific problems w/ this change, and the transaction ordering problem is an issue in the old spec as well. I'll start modifying the spec to match this new construction method (and include these examples) and create a new issue for the transaction ordering |
I think w3c/IndexedDB#77 should be sufficient. New construction sematics merged, so I'm closing this. |
Spec update: w3c/IndexedDB@4ca50ad |
I may have missed this, but should observers be called in the order in which they registered (i.e. called observe())? |
On Tue, Jun 28, 2016 at 12:43 PM Chris Mumford [email protected]
|
Observer creation should more closely resemble current observers in the web. We want to match something like IntersectionObserver.
This proposal only go over changes to the creation, we assume that the changes callback and behavior there is the same as in the Explainer.
Objectives
Example use cases:
We need to make sure we can always do the following:
Wants:
Proposal
I'll show examples first.
UI Element
Let's say we're a polymer or angular webapp, and we have databinding working. We rely on the guarantee that the observer will start immediately after the transaction it was created with.
Server sync worker
We want to synchronize changes to a webserver. Let's say we're storing descrete transformations, so it's only add operations. We rely on the guarantee that the observer will start immediately after the transaction it was created with.
Maintaining an in-memory data cache
IDB can be slow due to disk, so it's a good idea to have an in-memory cache. Note that we don't include values here, as we want to optimize our memory usage by reading in the cache in a larger batch, and at an opportune time. We rely on the guarantee that the observer will start immediately after the transaction it was created with.
Custom refresh logic
If we just want to know when an object store has changed. This isn't the most efficient, but this might be the 'starting block' websites use to transition to observers, as at some point they would read the database using a transaction to update their UI.
Note: This has been updated as per this comment below.
Summary
Other than the two step construction, we've split up the options. All options except ranges have moved to a flat options object passed into the observer creation. We could even just make the Map values for
observer.observe(db, txn, map)
be the ranges array itself, instead of an object that contains the 'ranges' attribute.I'm also having the database and transaction required arguments. In almost every use case, the person needs the guarentee that the observation starts after the read or write to the database. Otherwise changes can be leaked, where the observer didn't see them yet or the observer sees a change that we thought it wouldn't.
Possible changes / thoughts
db
argument and just use the connection from the transaction. This changes the current observer pattern in the web platform though, which ties the lifetime of the observer to the first argument. Since we're tieing to the database connection, then this makes sense to leave in there.The text was updated successfully, but these errors were encountered: