Re: [IDB] Lifetime of IDB objects

On Mon, Oct 22, 2012 at 2:00 AM, Jonas Sicking <jonas@sicking.cc> wrote:

> On Sun, Oct 21, 2012 at 5:01 PM, Joćo Eiras <joaoe@opera.com> wrote:
> >
> > Hi !
> >
> > The specification does not specify in detail what happens to several of
> the
> > object types once they have reached their purpose.
> >
> > For instance, IDBTransaction's abort and objectStore methods dispatch
> > InvalidStateError.
> >
> > However, IDBRequest and IDBCursor have properties which return other
> objects
> > like IDBRequest.source, IDBRequest.result, IDBRequest.transaction,
> > IDBCursor.source,
>
> The intent was for these properties to return the same value as they
> always did. Suggestions for how to make this more clear would be
> welcome.
>
> > IDBCursor.key, IDBCursor.primaryKey which behavior, after
> > the request has completed, is undefined or defined as returning the same
> > value (for source only it seems).
>
> These too don't change their value when a transaction is committed.
> The spec is hopefully pretty clear that these values are set to
> 'undefined' once the cursor has been iterated to the end though?
>
> > Having these objects keeping references to other objects after they have
> > completed, can represent extra memory overhead, while not very useful,
> > specially if the application is data heavy, like an offline main client
> with
> > lots of requests, or long blobs are used, and it prevents the garbage
> > collector from cleaning up more than it could, specially while a
> transaction
> > is active.
> >
> > I suggest that after an IDBRequest, IDBTransaction or IDBCursor complete,
> > all their properties are cleared (at least the non-trivial ones) so the
> > garbage collector can do it work. However, since that would cause the
> > properties to return later undefined/null, it is better if they just all
> > throw InvalidStateError when accessed after the object has reached it's
> > purpose.
>
> I definitely don't think we should be throwing more exceptions here. I
> don't see that someone is doing something inherently wrong when trying
> to access these properties after a transaction has been committed or
> aborted, so throwing an exception seems like it can just introduce
> breakage for authors.
>
> Likewise, returning null/undefined for these objects can cause code
> like "myrequest.source.name" to throw if accessed "too late".
>
> I don't think that the "retaining memory" problem is a particularly
> big one. Note that we'd only be retaining a small number of extra
> objects at the most. Only if a page holds on to a request do we end up
> keeping the store and transaction objects alive. Holding a transaction
> alive never ends up holding all the requests alive.
>
>
Agreed. If I'm recalling correctly, at this point the spec implicitly
requires that "upward" references are retained (e.g. request->transaction,
index->store, request->index/store, etc). "Downward" references are only
retained temporarily: transaction->request for unfinished requests, and
transaction->store / store->index for unfinished transactions, etc.

As long as script is not holding on to the "leaf" objects like
requests/cursors the memory usage as required by the spec shouldn't be
large.

If you can find a spec counter-example to this assertion, we should address
it in the spec - IIRC we added behavior to IDBTransaction.objectStore() and
IDBObjectStore.index() to throw after the transaction was finished for this
reason.



> > Btw, an error in http://www.w3.org/TR/IndexedDB/#widl-IDBCursor-source"This
> > function never returns null or throws an exception". Should be "This
> > property".
>
> Would be great if you could file a bug on this since I'm likely to
> forget otherwise.
>
> / Jonas
>
>

Received on Monday, 22 October 2012 17:10:25 UTC