Re: [IndexedDB] Current editor's draft

2010-07-27 Thread Jeremy Orlow
On Tue, Jul 27, 2010 at 4:38 PM, Jonas Sicking  wrote:

> On Tue, Jul 27, 2010 at 3:14 AM, Jeremy Orlow  wrote:
> > On Tue, Jul 27, 2010 at 12:22 AM, Jonas Sicking 
> wrote:
> >>
> >> On Sat, Jul 24, 2010 at 8:29 AM, Jeremy Orlow 
> wrote:
> >> >> >> And is it
> >> >> >> only possible to lock existing rows, or can you prevent new
> records
> >> >> >> from being created?
> >> >> >
> >> >> > There's no way to lock yet to be created rows since until a
> >> >> > transaction
> >> >> > ends, its effects cannot be made visible to other transactions.
> >> >>
> >> >> So if you have an objectStore with auto-incrementing indexes, there
> is
> >> >> the possibility that two dynamic transactions both can add a row to
> >> >> said objectStore at the same time. Both transactions would then add a
> >> >> row with the same autogenerated id (one higher than the highest id in
> >> >> the table). Upon commit, how is this conflict resolved?
> >> >>
> >> >> What if the objectStore didn't use auto-incrementing indexes, but you
> >> >> still had two separate dynamic transactions which both insert a row
> >> >> with the same key. How is the conflict resolved?
> >> >
> >> > I believe a common trick to reconcile this is stipulating that if you
> >> > add
> >> > 1000 "rows" the id's may not necessarily be 1000 sequential numbers.
> >> >  This
> >> > allows transactions to increment the id and leave it incremented even
> if
> >> > the
> >> > transaction fails.  Which also means that other transactions can be
> >> > grabbing
> >> > an ID of their own as well.  And if a transaction fails, well, we've
> >> > wasted
> >> > one possible ID.
> >>
> >> This does not answer the question what happens if two transactions add
> >> the same key value though?
> >
> > If you're using optimistic transactions, whichever commits first
> succeeds.
> >  Not sure with the pessimistic/lock-based implementations.
>
> That doesn't count as serializable, does it? It's not a dead-lock
> hazard, but a race condition where whoever commits last experiences
> dataloss unless properly handling the commit error.
>

If they don't handle commit errors, yes, you would have data loss.  I didn't
realize we were even considering trying to make dynamic transactions work
without the possibility of the commit failing.


> >> >> >> And is it possible to only use read-locking for
> >> >> >> some rows, but write-locking for others, in the same objectStore?
> >> >> >
> >> >> > An implementation could use shared locks for read operations even
> >> >> > though
> >> >> > the object store might have been opened in READ_WRITE mode, and
> later
> >> >> > upgrade the locks if the read data is being modified. However, I am
> >> >> > not keen
> >> >> > to push for this as a specced behavior.
> >> >>
> >> >> What do you mean by "an implementation could"? Is this left
> >> >> intentionally undefined and left up to the implementation? Doesn't
> >> >> that mean that there is significant risk that code could work very
> >> >> well in a conservative implementation, but often cause race
> conditions
> >> >> in a implementation that uses narrower locks? Wouldn't this result in
> >> >> a "race to the bottom" where implementations are forced to eventually
> >> >> use very wide locks in order to work well in websites?
> >> >>
> >> >> In general, there are a lot of details that are unclear in the
> dynamic
> >> >> transactions proposals. I'm also not sure if these things are unclear
> >> >> to me because they are intentionally left undefined, or if you guys
> >> >> just haven't had time yet to define the details?
> >> >>
> >> >> As the spec is now, as an implementor I'd have no idea of how to
> >> >> implement dynamic transactions. And as a user I'd have no idea what
> >> >> level of protection to expect from implementations, nor what
> >> >> strategies to use to avoid bugs.
> >> >>
> >> >> In all the development I've done deadlocks and race conditions are
> >> >> generally unacceptable, and instead strategies are developed that
> >> >> avoids them, such as always grab locks in the same order, and always
> >> >> grab locks when using shared data. I currently have no idea what
> >> >> strategy to recommend in IndexedDB documentation to developers to
> >> >> allow them to avoid race conditions and deadlocks.
> >> >>
> >> >> To get clarity in these questions, I'd *really* *really* like to see
> a
> >> >> more detailed proposal.
> >> >
> >> > I think a detailed proposal would be a good thing (maybe from Pablo or
> >> > Nikunj since they're who are really pushing them at this point), but
> at
> >> > the
> >> > same time, I think you're getting really bogged down in the details,
> >> > Jonas.
> >> > What we should be concerned about and speccing is the behavior the
> user
> >> > sees.  For example, can any operation on data fail due to transient
> >> > issues
> >> > (like deadlocks, serialization issues) or will the implementation
> shield
> >> > web
> >> > developers from this?  And will we guarantee 10

Re: [IndexedDB] Current editor's draft

2010-07-27 Thread Jonas Sicking
On Tue, Jul 27, 2010 at 3:14 AM, Jeremy Orlow  wrote:
> On Tue, Jul 27, 2010 at 12:22 AM, Jonas Sicking  wrote:
>>
>> On Sat, Jul 24, 2010 at 8:29 AM, Jeremy Orlow  wrote:
>> >> >> And is it
>> >> >> only possible to lock existing rows, or can you prevent new records
>> >> >> from being created?
>> >> >
>> >> > There's no way to lock yet to be created rows since until a
>> >> > transaction
>> >> > ends, its effects cannot be made visible to other transactions.
>> >>
>> >> So if you have an objectStore with auto-incrementing indexes, there is
>> >> the possibility that two dynamic transactions both can add a row to
>> >> said objectStore at the same time. Both transactions would then add a
>> >> row with the same autogenerated id (one higher than the highest id in
>> >> the table). Upon commit, how is this conflict resolved?
>> >>
>> >> What if the objectStore didn't use auto-incrementing indexes, but you
>> >> still had two separate dynamic transactions which both insert a row
>> >> with the same key. How is the conflict resolved?
>> >
>> > I believe a common trick to reconcile this is stipulating that if you
>> > add
>> > 1000 "rows" the id's may not necessarily be 1000 sequential numbers.
>> >  This
>> > allows transactions to increment the id and leave it incremented even if
>> > the
>> > transaction fails.  Which also means that other transactions can be
>> > grabbing
>> > an ID of their own as well.  And if a transaction fails, well, we've
>> > wasted
>> > one possible ID.
>>
>> This does not answer the question what happens if two transactions add
>> the same key value though?
>
> If you're using optimistic transactions, whichever commits first succeeds.
>  Not sure with the pessimistic/lock-based implementations.

That doesn't count as serializable, does it? It's not a dead-lock
hazard, but a race condition where whoever commits last experiences
dataloss unless properly handling the commit error.

>> >> >> And is it possible to only use read-locking for
>> >> >> some rows, but write-locking for others, in the same objectStore?
>> >> >
>> >> > An implementation could use shared locks for read operations even
>> >> > though
>> >> > the object store might have been opened in READ_WRITE mode, and later
>> >> > upgrade the locks if the read data is being modified. However, I am
>> >> > not keen
>> >> > to push for this as a specced behavior.
>> >>
>> >> What do you mean by "an implementation could"? Is this left
>> >> intentionally undefined and left up to the implementation? Doesn't
>> >> that mean that there is significant risk that code could work very
>> >> well in a conservative implementation, but often cause race conditions
>> >> in a implementation that uses narrower locks? Wouldn't this result in
>> >> a "race to the bottom" where implementations are forced to eventually
>> >> use very wide locks in order to work well in websites?
>> >>
>> >> In general, there are a lot of details that are unclear in the dynamic
>> >> transactions proposals. I'm also not sure if these things are unclear
>> >> to me because they are intentionally left undefined, or if you guys
>> >> just haven't had time yet to define the details?
>> >>
>> >> As the spec is now, as an implementor I'd have no idea of how to
>> >> implement dynamic transactions. And as a user I'd have no idea what
>> >> level of protection to expect from implementations, nor what
>> >> strategies to use to avoid bugs.
>> >>
>> >> In all the development I've done deadlocks and race conditions are
>> >> generally unacceptable, and instead strategies are developed that
>> >> avoids them, such as always grab locks in the same order, and always
>> >> grab locks when using shared data. I currently have no idea what
>> >> strategy to recommend in IndexedDB documentation to developers to
>> >> allow them to avoid race conditions and deadlocks.
>> >>
>> >> To get clarity in these questions, I'd *really* *really* like to see a
>> >> more detailed proposal.
>> >
>> > I think a detailed proposal would be a good thing (maybe from Pablo or
>> > Nikunj since they're who are really pushing them at this point), but at
>> > the
>> > same time, I think you're getting really bogged down in the details,
>> > Jonas.
>> > What we should be concerned about and speccing is the behavior the user
>> > sees.  For example, can any operation on data fail due to transient
>> > issues
>> > (like deadlocks, serialization issues) or will the implementation shield
>> > web
>> > developers from this?  And will we guarantee 100% serializable
>> > semantics?
>> >  (I strongly believe we should on both counts.)  How things are
>> > implemented,
>> > granularity of locks, or even if an implementation uses locks at all for
>> > dynamic transactions should be explicitly out of scope for any spec.
>> >  After
>> > all, it's only the behavior users care about.
>>
>> If we can guarantee no deadlocks and 100% serializable semantics, then
>> I agree, it doesn't matter beyond that. However I don

Re: [IndexedDB] Current editor's draft

2010-07-27 Thread Jeremy Orlow
On Tue, Jul 27, 2010 at 12:22 AM, Jonas Sicking  wrote:

> On Sat, Jul 24, 2010 at 8:29 AM, Jeremy Orlow  wrote:
> >> >> And is it
> >> >> only possible to lock existing rows, or can you prevent new records
> >> >> from being created?
> >> >
> >> > There's no way to lock yet to be created rows since until a
> transaction
> >> > ends, its effects cannot be made visible to other transactions.
> >>
> >> So if you have an objectStore with auto-incrementing indexes, there is
> >> the possibility that two dynamic transactions both can add a row to
> >> said objectStore at the same time. Both transactions would then add a
> >> row with the same autogenerated id (one higher than the highest id in
> >> the table). Upon commit, how is this conflict resolved?
> >>
> >> What if the objectStore didn't use auto-incrementing indexes, but you
> >> still had two separate dynamic transactions which both insert a row
> >> with the same key. How is the conflict resolved?
> >
> > I believe a common trick to reconcile this is stipulating that if you add
> > 1000 "rows" the id's may not necessarily be 1000 sequential numbers.
>  This
> > allows transactions to increment the id and leave it incremented even if
> the
> > transaction fails.  Which also means that other transactions can be
> grabbing
> > an ID of their own as well.  And if a transaction fails, well, we've
> wasted
> > one possible ID.
>
> This does not answer the question what happens if two transactions add
> the same key value though?
>

If you're using optimistic transactions, whichever commits first succeeds.
 Not sure with the pessimistic/lock-based implementations.


>  >> >> And is it possible to only use read-locking for
> >> >> some rows, but write-locking for others, in the same objectStore?
> >> >
> >> > An implementation could use shared locks for read operations even
> though
> >> > the object store might have been opened in READ_WRITE mode, and later
> >> > upgrade the locks if the read data is being modified. However, I am
> not keen
> >> > to push for this as a specced behavior.
> >>
> >> What do you mean by "an implementation could"? Is this left
> >> intentionally undefined and left up to the implementation? Doesn't
> >> that mean that there is significant risk that code could work very
> >> well in a conservative implementation, but often cause race conditions
> >> in a implementation that uses narrower locks? Wouldn't this result in
> >> a "race to the bottom" where implementations are forced to eventually
> >> use very wide locks in order to work well in websites?
> >>
> >> In general, there are a lot of details that are unclear in the dynamic
> >> transactions proposals. I'm also not sure if these things are unclear
> >> to me because they are intentionally left undefined, or if you guys
> >> just haven't had time yet to define the details?
> >>
> >> As the spec is now, as an implementor I'd have no idea of how to
> >> implement dynamic transactions. And as a user I'd have no idea what
> >> level of protection to expect from implementations, nor what
> >> strategies to use to avoid bugs.
> >>
> >> In all the development I've done deadlocks and race conditions are
> >> generally unacceptable, and instead strategies are developed that
> >> avoids them, such as always grab locks in the same order, and always
> >> grab locks when using shared data. I currently have no idea what
> >> strategy to recommend in IndexedDB documentation to developers to
> >> allow them to avoid race conditions and deadlocks.
> >>
> >> To get clarity in these questions, I'd *really* *really* like to see a
> >> more detailed proposal.
> >
> > I think a detailed proposal would be a good thing (maybe from Pablo or
> > Nikunj since they're who are really pushing them at this point), but at
> the
> > same time, I think you're getting really bogged down in the details,
> Jonas.
> > What we should be concerned about and speccing is the behavior the user
> > sees.  For example, can any operation on data fail due to transient
> issues
> > (like deadlocks, serialization issues) or will the implementation shield
> web
> > developers from this?  And will we guarantee 100% serializable semantics?
> >  (I strongly believe we should on both counts.)  How things are
> implemented,
> > granularity of locks, or even if an implementation uses locks at all for
> > dynamic transactions should be explicitly out of scope for any spec.
>  After
> > all, it's only the behavior users care about.
>
> If we can guarantee no deadlocks and 100% serializable semantics, then
> I agree, it doesn't matter beyond that. However I don't think the
> current proposals for dynamic transactions guarantee that. In fact, a
> central point of the dynamic transactions proposal seems to be that
> the author can grow the lock space dynamically, in an author defined
> order. As long as that is the case you can't prevent deadlocks other
> than by forbidding multiple concurrent (dynamic) transactions.
>

There has been a

Re: [IndexedDB] Current editor's draft

2010-07-26 Thread Jonas Sicking
On Sat, Jul 24, 2010 at 8:29 AM, Jeremy Orlow  wrote:
>> >> And is it
>> >> only possible to lock existing rows, or can you prevent new records
>> >> from being created?
>> >
>> > There's no way to lock yet to be created rows since until a transaction
>> > ends, its effects cannot be made visible to other transactions.
>>
>> So if you have an objectStore with auto-incrementing indexes, there is
>> the possibility that two dynamic transactions both can add a row to
>> said objectStore at the same time. Both transactions would then add a
>> row with the same autogenerated id (one higher than the highest id in
>> the table). Upon commit, how is this conflict resolved?
>>
>> What if the objectStore didn't use auto-incrementing indexes, but you
>> still had two separate dynamic transactions which both insert a row
>> with the same key. How is the conflict resolved?
>
> I believe a common trick to reconcile this is stipulating that if you add
> 1000 "rows" the id's may not necessarily be 1000 sequential numbers.  This
> allows transactions to increment the id and leave it incremented even if the
> transaction fails.  Which also means that other transactions can be grabbing
> an ID of their own as well.  And if a transaction fails, well, we've wasted
> one possible ID.

This does not answer the question what happens if two transactions add
the same key value though?

>> >> And is it possible to only use read-locking for
>> >> some rows, but write-locking for others, in the same objectStore?
>> >
>> > An implementation could use shared locks for read operations even though
>> > the object store might have been opened in READ_WRITE mode, and later
>> > upgrade the locks if the read data is being modified. However, I am not 
>> > keen
>> > to push for this as a specced behavior.
>>
>> What do you mean by "an implementation could"? Is this left
>> intentionally undefined and left up to the implementation? Doesn't
>> that mean that there is significant risk that code could work very
>> well in a conservative implementation, but often cause race conditions
>> in a implementation that uses narrower locks? Wouldn't this result in
>> a "race to the bottom" where implementations are forced to eventually
>> use very wide locks in order to work well in websites?
>>
>> In general, there are a lot of details that are unclear in the dynamic
>> transactions proposals. I'm also not sure if these things are unclear
>> to me because they are intentionally left undefined, or if you guys
>> just haven't had time yet to define the details?
>>
>> As the spec is now, as an implementor I'd have no idea of how to
>> implement dynamic transactions. And as a user I'd have no idea what
>> level of protection to expect from implementations, nor what
>> strategies to use to avoid bugs.
>>
>> In all the development I've done deadlocks and race conditions are
>> generally unacceptable, and instead strategies are developed that
>> avoids them, such as always grab locks in the same order, and always
>> grab locks when using shared data. I currently have no idea what
>> strategy to recommend in IndexedDB documentation to developers to
>> allow them to avoid race conditions and deadlocks.
>>
>> To get clarity in these questions, I'd *really* *really* like to see a
>> more detailed proposal.
>
> I think a detailed proposal would be a good thing (maybe from Pablo or
> Nikunj since they're who are really pushing them at this point), but at the
> same time, I think you're getting really bogged down in the details, Jonas.
> What we should be concerned about and speccing is the behavior the user
> sees.  For example, can any operation on data fail due to transient issues
> (like deadlocks, serialization issues) or will the implementation shield web
> developers from this?  And will we guarantee 100% serializable semantics?
>  (I strongly believe we should on both counts.)  How things are implemented,
> granularity of locks, or even if an implementation uses locks at all for
> dynamic transactions should be explicitly out of scope for any spec.  After
> all, it's only the behavior users care about.

If we can guarantee no deadlocks and 100% serializable semantics, then
I agree, it doesn't matter beyond that. However I don't think the
current proposals for dynamic transactions guarantee that. In fact, a
central point of the dynamic transactions proposal seems to be that
the author can grow the lock space dynamically, in an author defined
order. As long as that is the case you can't prevent deadlocks other
than by forbidding multiple concurrent (dynamic) transactions.

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-24 Thread Jeremy Orlow
On Fri, Jul 23, 2010 at 4:21 PM, Jonas Sicking  wrote:

> On Fri, Jul 23, 2010 at 8:09 AM, Nikunj Mehta  wrote:
> >
> > On Jul 22, 2010, at 11:27 AM, Jonas Sicking wrote:
> >
> >> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta 
> wrote:
> >>>
> >>> On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
> >>>
> 
>  From: jor...@google.com [mailto:jor...@google.com] On Behalf Of
> Jeremy Orlow
>  Sent: Thursday, July 15, 2010 8:41 AM
> 
>  On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu 
> wrote:
>  On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow 
> wrote:
> > On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu 
> wrote:
> >>
> >> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow 
> wrote:
> >> Nikunj, could you clarify how locking works for the dynamic
> >> transactions proposal that is in the spec draft right now?
> >
> > I'd definitely like to hear what Nikunj originally intended here.
> >>
> 
>  Hmm, after re-reading the current spec, my understanding is that:
> 
>  - Scope consists in a set of object stores that the transaction
> operates
>  on.
>  - A connection may have zero or one active transactions.
>  - There may not be any overlap among the scopes of all active
>  transactions (static or dynamic) in a given database. So you
> cannot
>  have two READ_ONLY static transactions operating simultaneously
> over
>  the same object store.
>  - The granularity of locking for dynamic transactions is not
> specified
>  (all the spec says about this is "do not acquire locks on any
> database
>  objects now. Locks are obtained as the application attempts to
> access
>  those objects").
>  - Using dynamic transactions can lead to dealocks.
> 
>  Given the changes in 9975, here's what I think the spec should say
> for
>  now:
> 
>  - There can be multiple active static transactions, as long as
> their
>  scopes do not overlap, or the overlapping objects are locked in
> modes
>  that are not mutually exclusive.
>  - [If we decide to keep dynamic transactions] There can be
> multiple
>  active dynamic transactions. TODO: Decide what to do if they start
>  overlapping:
>    -- proceed anyway and then fail at commit time in case of
>  conflicts. However, I think this would require implementing MVCC,
> so
>  implementations that use SQLite would be in trouble?
> >>>
> >>> Such implementations could just lock more conservatively (i.e. not
> allow
> >>> other transactions during a dynamic transaction).
> >>>
> >> Umm, I am not sure how useful dynamic transactions would be in that
> >> case...Ben Turner made the same comment earlier in the thread and I
> >> agree with him.
> >>
> >> Yes, dynamic transactions would not be useful on those
> implementations, but the point is that you could still implement the spec
> without a MVCC backend--though it would limit the concurrency that's
> possible.  Thus "implementations that use SQLite would" NOT necessarily "be
> in trouble".
> 
>  Interesting, I'm glad this conversation came up so we can sync up on
> assumptions...mine where:
>  - There can be multiple transactions of any kind active against a
> given database session (see note below)
>  - Multiple static transactions may overlap as long as they have
> compatible modes, which in practice means they are all READ_ONLY
>  - Dynamic transactions have arbitrary granularity for scope
> (implementation specific, down to row-level locking/scope)
> >>>
> >>> Dynamic transactions should be able to lock as little as necessary and
> as late as required.
> >>
> >> So dynamic transactions, as defined in your proposal, didn't lock on a
> >> whole-objectStore level?
> >
> > That is not correct. I said that the original intention was to make
> dynamic transactions lock as little and as late as possible. However, the
> current spec does not state explicitly that dynamic transactions should not
> lock the entire objectStore, but it could.
> >
> >> If so, how does the author specify which rows
> >> are locked?
> >
> > Again, the intention is to do this directly from the actions performed by
> the application and the affected keys
>
> The two above statements confuse me.
>
> The important question is: Pablo is clearly suggesting that dynamic
> transactions should not use whole-objectStore locks, but rather
> row-level locks, or possibly range locks. Is this what you are
> suggesting too?
>

I'm not sure why this matters at all.  The point is that we need to use some
locking scheme that ensures serializability and ideally it'd be done in a
way that allows a good deal of concurrency.  I don't think the spec should
force any particular locking scheme (or pessimistic transactions in
general).


> >> And why is the

Re: [IndexedDB] Current editor's draft

2010-07-23 Thread Jonas Sicking
On Fri, Jul 23, 2010 at 8:09 AM, Nikunj Mehta  wrote:
>
> On Jul 22, 2010, at 11:27 AM, Jonas Sicking wrote:
>
>> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta  wrote:
>>>
>>> On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>>>

 From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy 
 Orlow
 Sent: Thursday, July 15, 2010 8:41 AM

 On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:
 On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  
> wrote:
>>
>> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  
>> wrote:
>> Nikunj, could you clarify how locking works for the dynamic
>> transactions proposal that is in the spec draft right now?
>
> I'd definitely like to hear what Nikunj originally intended here.
>>

 Hmm, after re-reading the current spec, my understanding is that:

 - Scope consists in a set of object stores that the transaction 
 operates
 on.
 - A connection may have zero or one active transactions.
 - There may not be any overlap among the scopes of all active
 transactions (static or dynamic) in a given database. So you cannot
 have two READ_ONLY static transactions operating simultaneously over
 the same object store.
 - The granularity of locking for dynamic transactions is not specified
 (all the spec says about this is "do not acquire locks on any database
 objects now. Locks are obtained as the application attempts to access
 those objects").
 - Using dynamic transactions can lead to dealocks.

 Given the changes in 9975, here's what I think the spec should say for
 now:

 - There can be multiple active static transactions, as long as their
 scopes do not overlap, or the overlapping objects are locked in modes
 that are not mutually exclusive.
 - [If we decide to keep dynamic transactions] There can be multiple
 active dynamic transactions. TODO: Decide what to do if they start
 overlapping:
   -- proceed anyway and then fail at commit time in case of
 conflicts. However, I think this would require implementing MVCC, so
 implementations that use SQLite would be in trouble?
>>>
>>> Such implementations could just lock more conservatively (i.e. not allow
>>> other transactions during a dynamic transaction).
>>>
>> Umm, I am not sure how useful dynamic transactions would be in that
>> case...Ben Turner made the same comment earlier in the thread and I
>> agree with him.
>>
>> Yes, dynamic transactions would not be useful on those implementations, 
>> but the point is that you could still implement the spec without a MVCC 
>> backend--though it would limit the concurrency that's possible.  Thus 
>> "implementations that use SQLite would" NOT necessarily "be in trouble".

 Interesting, I'm glad this conversation came up so we can sync up on 
 assumptions...mine where:
 - There can be multiple transactions of any kind active against a given 
 database session (see note below)
 - Multiple static transactions may overlap as long as they have compatible 
 modes, which in practice means they are all READ_ONLY
 - Dynamic transactions have arbitrary granularity for scope 
 (implementation specific, down to row-level locking/scope)
>>>
>>> Dynamic transactions should be able to lock as little as necessary and as 
>>> late as required.
>>
>> So dynamic transactions, as defined in your proposal, didn't lock on a
>> whole-objectStore level?
>
> That is not correct. I said that the original intention was to make dynamic 
> transactions lock as little and as late as possible. However, the current 
> spec does not state explicitly that dynamic transactions should not lock the 
> entire objectStore, but it could.
>
>> If so, how does the author specify which rows
>> are locked?
>
> Again, the intention is to do this directly from the actions performed by the 
> application and the affected keys

The two above statements confuse me.

The important question is: Pablo is clearly suggesting that dynamic
transactions should not use whole-objectStore locks, but rather
row-level locks, or possibly range locks. Is this what you are
suggesting too?

>> And why is then openObjectStore a asynchronous operation
>> that could possibly fail, since at the time when openObjectStore is
>> called, the implementation doesn't know which rows are going to be
>> accessed and so can't determine if a deadlock is occurring?
>
> The open call is used to check if some static transaction has the entire 
> store locked for READ_WRITE. If so, the open call will block.

Given that synchronous vs. asynchronous is just an optimization, I'll
defer this topic until I understand 

Re: [IndexedDB] Current editor's draft

2010-07-23 Thread Nikunj Mehta

On Jul 22, 2010, at 11:27 AM, Jonas Sicking wrote:

> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta  wrote:
>> 
>> On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>> 
>>> 
>>> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy Orlow
>>> Sent: Thursday, July 15, 2010 8:41 AM
>>> 
>>> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:
>>> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
 On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:
> 
> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
> Nikunj, could you clarify how locking works for the dynamic
> transactions proposal that is in the spec draft right now?
 
 I'd definitely like to hear what Nikunj originally intended here.
> 
>>> 
>>> Hmm, after re-reading the current spec, my understanding is that:
>>> 
>>> - Scope consists in a set of object stores that the transaction operates
>>> on.
>>> - A connection may have zero or one active transactions.
>>> - There may not be any overlap among the scopes of all active
>>> transactions (static or dynamic) in a given database. So you cannot
>>> have two READ_ONLY static transactions operating simultaneously over
>>> the same object store.
>>> - The granularity of locking for dynamic transactions is not specified
>>> (all the spec says about this is "do not acquire locks on any database
>>> objects now. Locks are obtained as the application attempts to access
>>> those objects").
>>> - Using dynamic transactions can lead to dealocks.
>>> 
>>> Given the changes in 9975, here's what I think the spec should say for
>>> now:
>>> 
>>> - There can be multiple active static transactions, as long as their
>>> scopes do not overlap, or the overlapping objects are locked in modes
>>> that are not mutually exclusive.
>>> - [If we decide to keep dynamic transactions] There can be multiple
>>> active dynamic transactions. TODO: Decide what to do if they start
>>> overlapping:
>>>   -- proceed anyway and then fail at commit time in case of
>>> conflicts. However, I think this would require implementing MVCC, so
>>> implementations that use SQLite would be in trouble?
>> 
>> Such implementations could just lock more conservatively (i.e. not allow
>> other transactions during a dynamic transaction).
>> 
> Umm, I am not sure how useful dynamic transactions would be in that
> case...Ben Turner made the same comment earlier in the thread and I
> agree with him.
> 
> Yes, dynamic transactions would not be useful on those implementations, 
> but the point is that you could still implement the spec without a MVCC 
> backend--though it would limit the concurrency that's possible.  Thus 
> "implementations that use SQLite would" NOT necessarily "be in trouble".
>>> 
>>> Interesting, I'm glad this conversation came up so we can sync up on 
>>> assumptions...mine where:
>>> - There can be multiple transactions of any kind active against a given 
>>> database session (see note below)
>>> - Multiple static transactions may overlap as long as they have compatible 
>>> modes, which in practice means they are all READ_ONLY
>>> - Dynamic transactions have arbitrary granularity for scope (implementation 
>>> specific, down to row-level locking/scope)
>> 
>> Dynamic transactions should be able to lock as little as necessary and as 
>> late as required.
> 
> So dynamic transactions, as defined in your proposal, didn't lock on a
> whole-objectStore level?

That is not correct. I said that the original intention was to make dynamic 
transactions lock as little and as late as possible. However, the current spec 
does not state explicitly that dynamic transactions should not lock the entire 
objectStore, but it could.

> If so, how does the author specify which rows
> are locked?

Again, the intention is to do this directly from the actions performed by the 
application and the affected keys

> And why is then openObjectStore a asynchronous operation
> that could possibly fail, since at the time when openObjectStore is
> called, the implementation doesn't know which rows are going to be
> accessed and so can't determine if a deadlock is occurring?

The open call is used to check if some static transaction has the entire store 
locked for READ_WRITE. If so, the open call will block. 

> And is it
> only possible to lock existing rows, or can you prevent new records
> from being created?

There's no way to lock yet to be created rows since until a transaction ends, 
its effects cannot be made visible to other transactions.

> And is it possible to only use read-locking for
> some rows, but write-locking for others, in the same objectStore?

An implementation could use shared locks for read operations even though the 
object store might have been opened in READ_WRITE mode, and later upgrade the 
locks i

Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jeremy Orlow
On Thu, Jul 22, 2010 at 8:39 PM, Pablo Castro wrote:

>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Thursday, July 22, 2010 5:25 PM
>
> >> >> Regarding deadlocks, that's right, the implementation cannot
> determine if
> >> >> a deadlock will occur ahead of time. Sophisticated implementations
> could
> >> >> track locks/owners and do deadlock detection, although a simple
> >> >> timeout-based mechanism is probably enough for IndexedDB.
> >> >
> >> > Simple implementations will not deadlock because they're only doing
> object
> >> > store level locking in a constant locking order.
>
> Well, it's not really simple vs sophisticated, but whether they do
> dynamically scoped transactions or not, isn't it? If you do dynamic
> transactions, then regardless of the granularity of your locks, code will
> grow the lock space in a way that you cannot predict so you can't use a
> well-known locking order, so deadlocks are not avoidable.
>

As I've mentioned before, you can simply not run more than one dynamic
transaction at a time (and only start locking for a static transaction when
all locks are available and doing the locking atomically) to implement the
dynamic transactions from an API perspective.


> >> >  Sophisticated implementations will be doing key level (IndexedDB's
> analog
> >> > to row level) locking with deadlock detection or using methods to
> completely
> >> > avoid it.  I'm not sure I'm comfortable with having one or two
> in-between
> >> > implementations relying on timeouts to resolve deadlocks.
>
> Deadlock detection is quite a bit to ask from the storage engine. From the
> developer's perspective, the difference between deadlock detection and
> timeouts for deadlocks is the fact that the timeout approach will take a bit
> longer, and the error won't be as definitive. I don't think this particular
> difference is enough to require deadlock detection.
>

This means that some web apps on some platforms will hang for seconds (or
minutes?) at a time in a hard to debug fashion.  I don't think this is
acceptable for a web standard.


> >> > Of course, if we're breaking deadlocks that means that web developers
> need
> >> > to handle this error case on every async request they make.  As such,
> I'd
> >> > rather that we require implementations to make deadlocks impossible.
>  This
> >> > means that they either need to be conservative about locking or to do
> MVCC
> >> > (or something similar) so that transactions can continue on even
> beyond the
> >> > point where we know they can't be serialized.  This would
> be consistent with
> >> > our usual policy of trying to put as much of the burden as is
> practical on
> >> > the browser developers rather than web developers.
>
> Same as above...MVCC is quite a bit to mandate from all implementations.
> For example, I'm not sure but from my basic understanding of SQLite I think
> it always does straight up locking and doesn't have support for versioning.
>

As I mentioned, there's a simpler behavior that implementations can
implement if they feel MVCC is too complicated.  If dynamic transactions are
included in v1 of the spec, this will almost certainly be what we do
initially in Chromium.

Of course, I'd rather we just take it out of v1 for reasons like what's
coming up in this thread.


>  >> >>
> >> >> As for locking only existing rows, that depends on how much isolation
> we
> >> >> want to provide. If we want "serializable", then we'd have to put in
> things
> >> >> such as range locks and locks on non-existing keys so reads are
> consistent
> >> >> w.r.t. newly created rows.
> >> >
> >> > For the record, I am completely against anything other than
> "serializable"
> >> > being the default.  Everything a web developer deals with follows run
> to
> >> > completion.  If you want to have optional modes that relax things in
> terms
> >> > of serializability, maybe we should start a new thread?
> >>
> >> Agreed.
> >>
> >> I was against dynamic transactions even when they used
> >> whole-objectStore locking. So I'm even more so now that people are
> >> proposing row-level locking. But I'd like to understand what people
> >> are proposing, and make sure that what is being proposed is a coherent
> >> solution, so that we can correctly evaluate it's risks versus
> >> benefits.
>
> The way I see the risk/benefit tradeoff of dynamic transactions: they bring
> better concurrency and more flexibility at the cost of new failure modes. I
> think that weighing them in those terms is more important than the specifics
> such as whether it's okay to have timeouts versus explicit deadlock errors.
>

I think we should only add additional failure modes when there are very
strong reasons why they're worth it.  And simplifying things for
implementors is not an acceptable reason to add (fairly complex,
non-deterministic) failure modes.

J


RE: [IndexedDB] Current editor's draft

2010-07-22 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Thursday, July 22, 2010 5:30 PM

>> On Thu, Jul 22, 2010 at 5:26 PM, Pablo Castro
>>  wrote:
>> >
>> > From: Jonas Sicking [mailto:jo...@sicking.cc]
>> > Sent: Thursday, July 22, 2010 5:18 PM
>> >
>> >>> > The author doesn't explicitly specify which rows to lock. All rows 
>> >>> > that you "see" become locked (e.g. through get(), put(), scanning with 
>> >>> > a cursor, etc.). If you start the transaction as read-only then 
>> >>> > they'll all have shared locks. If you start the transaction as 
>> >>> > read-write then we can choose whether the implementation should always 
>> >>> > attempt to take exclusive locks or if it should take shared locks on 
>> >>> > read, and attempt to upgrade to an exclusive lock on first write (this 
>> >>> > affects failure modes a bit).

>> >
>> >>> What counts as "see"? If you iterate using an index-cursor all the
>> >>> rows that have some value between "A" and "B", but another, not yet
>> >>> committed, transaction changes a row such that its value now is
>> >>> between "A" and "B", what happens?
>> >
>> > We need to design something a bit more formal that covers the whole 
>> > spectrum. As a short answer, assuming we want to have "serializable" as 
>> > our isolation level, then we'd have a range lock that goes from the start 
>> > of a cursor to the point you've reached, so if you were to start another 
>> > cursor you'd be guaranteed the exact same view of the world. In that case 
>> > it wouldn't be possible for other transaction to insert a row between two 
>> > rows you scanned through with a cursor.
>>
>> How would you prevent that? Would a call to .modify() or .put() block
>> until the other transaction finishes? With appropriate timeouts on
>> deadlocks of course.

That's right, calls would block if they need to acquire a lock for a key or a 
range and there is an incompatible lock present that overlaps somehow with that.

-pablo




RE: [IndexedDB] Current editor's draft

2010-07-22 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Thursday, July 22, 2010 5:25 PM

>> >> Regarding deadlocks, that's right, the implementation cannot determine if
>> >> a deadlock will occur ahead of time. Sophisticated implementations could
>> >> track locks/owners and do deadlock detection, although a simple
>> >> timeout-based mechanism is probably enough for IndexedDB.
>> >
>> > Simple implementations will not deadlock because they're only doing object
>> > store level locking in a constant locking order.

Well, it's not really simple vs sophisticated, but whether they do dynamically 
scoped transactions or not, isn't it? If you do dynamic transactions, then 
regardless of the granularity of your locks, code will grow the lock space in a 
way that you cannot predict so you can't use a well-known locking order, so 
deadlocks are not avoidable. 

>> >  Sophisticated implementations will be doing key level (IndexedDB's analog
>> > to row level) locking with deadlock detection or using methods to 
>> > completely
>> > avoid it.  I'm not sure I'm comfortable with having one or two in-between
>> > implementations relying on timeouts to resolve deadlocks.

Deadlock detection is quite a bit to ask from the storage engine. From the 
developer's perspective, the difference between deadlock detection and timeouts 
for deadlocks is the fact that the timeout approach will take a bit longer, and 
the error won't be as definitive. I don't think this particular difference is 
enough to require deadlock detection.

>> > Of course, if we're breaking deadlocks that means that web developers need
>> > to handle this error case on every async request they make.  As such, I'd
>> > rather that we require implementations to make deadlocks impossible.  This
>> > means that they either need to be conservative about locking or to do MVCC
>> > (or something similar) so that transactions can continue on even beyond the
>> > point where we know they can't be serialized.  This would 
>> > be consistent with
>> > our usual policy of trying to put as much of the burden as is practical on
>> > the browser developers rather than web developers.

Same as above...MVCC is quite a bit to mandate from all implementations. For 
example, I'm not sure but from my basic understanding of SQLite I think it 
always does straight up locking and doesn't have support for versioning.

>> >>
>> >> As for locking only existing rows, that depends on how much isolation we
>> >> want to provide. If we want "serializable", then we'd have to put in 
>> >> things
>> >> such as range locks and locks on non-existing keys so reads are consistent
>> >> w.r.t. newly created rows.
>> >
>> > For the record, I am completely against anything other than "serializable"
>> > being the default.  Everything a web developer deals with follows run to
>> > completion.  If you want to have optional modes that relax things in terms
>> > of serializability, maybe we should start a new thread?
>>
>> Agreed.
>>
>> I was against dynamic transactions even when they used
>> whole-objectStore locking. So I'm even more so now that people are
>> proposing row-level locking. But I'd like to understand what people
>> are proposing, and make sure that what is being proposed is a coherent
>> solution, so that we can correctly evaluate it's risks versus
>> benefits.

The way I see the risk/benefit tradeoff of dynamic transactions: they bring 
better concurrency and more flexibility at the cost of new failure modes. I 
think that weighing them in those terms is more important than the specifics 
such as whether it's okay to have timeouts versus explicit deadlock errors. 

-pablo





Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jonas Sicking
On Thu, Jul 22, 2010 at 5:26 PM, Pablo Castro
 wrote:
>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Thursday, July 22, 2010 5:18 PM
>
>>> > The author doesn't explicitly specify which rows to lock. All rows that 
>>> > you "see" become locked (e.g. through get(), put(), scanning with a 
>>> > cursor, etc.). If you start the transaction as read-only then they'll all 
>>> > have shared locks. If you start the transaction as read-write then we can 
>>> > choose whether the implementation should always attempt to take exclusive 
>>> > locks or if it should take shared locks on read, and attempt to upgrade 
>>> > to an exclusive lock on first write (this affects failure modes a bit).
>
>>> What counts as "see"? If you iterate using an index-cursor all the
>>> rows that have some value between "A" and "B", but another, not yet
>>> committed, transaction changes a row such that its value now is
>>> between "A" and "B", what happens?
>
> We need to design something a bit more formal that covers the whole spectrum. 
> As a short answer, assuming we want to have "serializable" as our isolation 
> level, then we'd have a range lock that goes from the start of a cursor to 
> the point you've reached, so if you were to start another cursor you'd be 
> guaranteed the exact same view of the world. In that case it wouldn't be 
> possible for other transaction to insert a row between two rows you scanned 
> through with a cursor.

How would you prevent that? Would a call to .modify() or .put() block
until the other transaction finishes? With appropriate timeouts on
deadlocks of course.

/ Jonas



RE: [IndexedDB] Current editor's draft

2010-07-22 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Thursday, July 22, 2010 5:18 PM

>> > The author doesn't explicitly specify which rows to lock. All rows that 
>> > you "see" become locked (e.g. through get(), put(), scanning with a 
>> > cursor, etc.). If you start the transaction as read-only then they'll all 
>> > have shared locks. If you start the transaction as read-write then we can 
>> > choose whether the implementation should always attempt to take exclusive 
>> > locks or if it should take shared locks on read, and attempt to upgrade to 
>> > an exclusive lock on first write (this affects failure modes a bit).

>> What counts as "see"? If you iterate using an index-cursor all the
>> rows that have some value between "A" and "B", but another, not yet
>> committed, transaction changes a row such that its value now is
>> between "A" and "B", what happens?

We need to design something a bit more formal that covers the whole spectrum. 
As a short answer, assuming we want to have "serializable" as our isolation 
level, then we'd have a range lock that goes from the start of a cursor to the 
point you've reached, so if you were to start another cursor you'd be 
guaranteed the exact same view of the world. In that case it wouldn't be 
possible for other transaction to insert a row between two rows you scanned 
through with a cursor.

-pablo




Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jonas Sicking
On Thu, Jul 22, 2010 at 5:18 PM, Jeremy Orlow  wrote:
> On Thu, Jul 22, 2010 at 7:41 PM, Pablo Castro 
> wrote:
>>
>> From: Jonas Sicking [mailto:jo...@sicking.cc]
>> Sent: Thursday, July 22, 2010 11:27 AM
>>
>> >> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta 
>> >> wrote:
>> >> >
>> >> > On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>> >> >
>> >> >>
>> >> >> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of
>> >> >> Jeremy Orlow
>> >> >> Sent: Thursday, July 15, 2010 8:41 AM
>> >> >>
>> >> >> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu 
>> >> >> wrote:
>> >> >> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow 
>> >> >> wrote:
>> >> >>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu
>> >> >>>  wrote:
>> >> 
>> >>  On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow
>> >>   wrote:
>> >>  Nikunj, could you clarify how locking works for the dynamic
>> >>  transactions proposal that is in the spec draft right now?
>> >> >>>
>> >> >>> I'd definitely like to hear what Nikunj originally intended
>> >> >>> here.
>> >> 
>> >> >>
>> >> >> Hmm, after re-reading the current spec, my understanding is
>> >> >> that:
>> >> >>
>> >> >> - Scope consists in a set of object stores that the transaction
>> >> >> operates
>> >> >> on.
>> >> >> - A connection may have zero or one active transactions.
>> >> >> - There may not be any overlap among the scopes of all active
>> >> >> transactions (static or dynamic) in a given database. So you
>> >> >> cannot
>> >> >> have two READ_ONLY static transactions operating simultaneously
>> >> >> over
>> >> >> the same object store.
>> >> >> - The granularity of locking for dynamic transactions is not
>> >> >> specified
>> >> >> (all the spec says about this is "do not acquire locks on any
>> >> >> database
>> >> >> objects now. Locks are obtained as the application attempts to
>> >> >> access
>> >> >> those objects").
>> >> >> - Using dynamic transactions can lead to dealocks.
>> >> >>
>> >> >> Given the changes in 9975, here's what I think the spec should
>> >> >> say for
>> >> >> now:
>> >> >>
>> >> >> - There can be multiple active static transactions, as long as
>> >> >> their
>> >> >> scopes do not overlap, or the overlapping objects are locked in
>> >> >> modes
>> >> >> that are not mutually exclusive.
>> >> >> - [If we decide to keep dynamic transactions] There can be
>> >> >> multiple
>> >> >> active dynamic transactions. TODO: Decide what to do if they
>> >> >> start
>> >> >> overlapping:
>> >> >>   -- proceed anyway and then fail at commit time in case of
>> >> >> conflicts. However, I think this would require implementing
>> >> >> MVCC, so
>> >> >> implementations that use SQLite would be in trouble?
>> >> >
>> >> > Such implementations could just lock more conservatively (i.e.
>> >> > not allow
>> >> > other transactions during a dynamic transaction).
>> >> >
>> >>  Umm, I am not sure how useful dynamic transactions would be in
>> >>  that
>> >>  case...Ben Turner made the same comment earlier in the thread and
>> >>  I
>> >>  agree with him.
>> >> 
>> >>  Yes, dynamic transactions would not be useful on those
>> >>  implementations, but the point is that you could still implement the 
>> >>  spec
>> >>  without a MVCC backend--though it >> would limit the concurrency 
>> >>  that's
>> >>  possible.  Thus "implementations that use SQLite would" NOT 
>> >>  necessarily "be
>> >>  in trouble".
>> >> >>
>> >> >> Interesting, I'm glad this conversation came up so we can sync up on
>> >> >> assumptions...mine where:
>> >> >> - There can be multiple transactions of any kind active against a
>> >> >> given database session (see note below)
>> >> >> - Multiple static transactions may overlap as long as they have
>> >> >> compatible modes, which in practice means they are all READ_ONLY
>> >> >> - Dynamic transactions have arbitrary granularity for scope
>> >> >> (implementation specific, down to row-level locking/scope)
>> >> >
>> >> > Dynamic transactions should be able to lock as little as necessary
>> >> > and as late as required.
>> >>
>> >> So dynamic transactions, as defined in your proposal, didn't lock on a
>> >> whole-objectStore level? If so, how does the author specify which rows
>> >> are locked? And why is then openObjectStore a asynchronous operation
>> >> that could possibly fail, since at the time when openObjectStore is
>> >> called, the implementation doesn't know which rows are going to be
>> >> accessed and so can't determine if a deadlock is occurring? And is it
>> >> only possible to lock existing rows, or can you prevent new records
>> >> from being created? And is it possible to only use read-locking for
>> >> some rows, but write-locking for others, in the same obje

Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jeremy Orlow
On Thu, Jul 22, 2010 at 7:41 PM, Pablo Castro wrote:

>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Thursday, July 22, 2010 11:27 AM
>
> >> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta 
> wrote:
> >> >
> >> > On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
> >> >
> >> >>
> >> >> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of
> Jeremy Orlow
> >> >> Sent: Thursday, July 15, 2010 8:41 AM
> >> >>
> >> >> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu 
> wrote:
> >> >> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow 
> wrote:
> >> >>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu 
> wrote:
> >> 
> >>  On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow 
> wrote:
> >>  Nikunj, could you clarify how locking works for the dynamic
> >>  transactions proposal that is in the spec draft right now?
> >> >>>
> >> >>> I'd definitely like to hear what Nikunj originally intended
> here.
> >> 
> >> >>
> >> >> Hmm, after re-reading the current spec, my understanding is that:
> >> >>
> >> >> - Scope consists in a set of object stores that the transaction
> operates
> >> >> on.
> >> >> - A connection may have zero or one active transactions.
> >> >> - There may not be any overlap among the scopes of all active
> >> >> transactions (static or dynamic) in a given database. So you
> cannot
> >> >> have two READ_ONLY static transactions operating simultaneously
> over
> >> >> the same object store.
> >> >> - The granularity of locking for dynamic transactions is not
> specified
> >> >> (all the spec says about this is "do not acquire locks on any
> database
> >> >> objects now. Locks are obtained as the application attempts to
> access
> >> >> those objects").
> >> >> - Using dynamic transactions can lead to dealocks.
> >> >>
> >> >> Given the changes in 9975, here's what I think the spec should
> say for
> >> >> now:
> >> >>
> >> >> - There can be multiple active static transactions, as long as
> their
> >> >> scopes do not overlap, or the overlapping objects are locked in
> modes
> >> >> that are not mutually exclusive.
> >> >> - [If we decide to keep dynamic transactions] There can be
> multiple
> >> >> active dynamic transactions. TODO: Decide what to do if they
> start
> >> >> overlapping:
> >> >>   -- proceed anyway and then fail at commit time in case of
> >> >> conflicts. However, I think this would require implementing MVCC,
> so
> >> >> implementations that use SQLite would be in trouble?
> >> >
> >> > Such implementations could just lock more conservatively (i.e. not
> allow
> >> > other transactions during a dynamic transaction).
> >> >
> >>  Umm, I am not sure how useful dynamic transactions would be in that
> >>  case...Ben Turner made the same comment earlier in the thread and I
> >>  agree with him.
> >> 
> >>  Yes, dynamic transactions would not be useful on those
> implementations, but the point is that you could still implement the spec
> without a MVCC backend--though it >> would limit the concurrency that's
> possible.  Thus "implementations that use SQLite would" NOT necessarily "be
> in trouble".
> >> >>
> >> >> Interesting, I'm glad this conversation came up so we can sync up on
> assumptions...mine where:
> >> >> - There can be multiple transactions of any kind active against a
> given database session (see note below)
> >> >> - Multiple static transactions may overlap as long as they have
> compatible modes, which in practice means they are all READ_ONLY
> >> >> - Dynamic transactions have arbitrary granularity for scope
> (implementation specific, down to row-level locking/scope)
> >> >
> >> > Dynamic transactions should be able to lock as little as necessary and
> as late as required.
> >>
> >> So dynamic transactions, as defined in your proposal, didn't lock on a
> >> whole-objectStore level? If so, how does the author specify which rows
> >> are locked? And why is then openObjectStore a asynchronous operation
> >> that could possibly fail, since at the time when openObjectStore is
> >> called, the implementation doesn't know which rows are going to be
> >> accessed and so can't determine if a deadlock is occurring? And is it
> >> only possible to lock existing rows, or can you prevent new records
> >> from being created? And is it possible to only use read-locking for
> >> some rows, but write-locking for others, in the same objectStore?
>
> That's my interpretation, dynamic transactions don't lock whole object
> stores. To me dynamic transactions are the same as what typical SQL
> databases do today.
>
> The author doesn't explicitly specify which rows to lock. All rows that you
> "see" become locked (e.g. through get(), put(), scanning with a cursor,
> etc.). If you start the transaction as read-only then they'll all have
> shared locks. If you start the transaction as read-write then we c

Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jonas Sicking
On Thu, Jul 22, 2010 at 4:41 PM, Pablo Castro
 wrote:
>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Thursday, July 22, 2010 11:27 AM
>
>>> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta  wrote:
>>> >
>>> > On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>>> >
>>> >>
>>> >> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy 
>>> >> Orlow
>>> >> Sent: Thursday, July 15, 2010 8:41 AM
>>> >>
>>> >> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  
>>> >> wrote:
>>> >> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  
>>> >> wrote:
>>> >>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  
>>> >>> wrote:
>>> 
>>>  On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  
>>>  wrote:
>>>  Nikunj, could you clarify how locking works for the dynamic
>>>  transactions proposal that is in the spec draft right now?
>>> >>>
>>> >>> I'd definitely like to hear what Nikunj originally intended here.
>>> 
>>> >>
>>> >> Hmm, after re-reading the current spec, my understanding is that:
>>> >>
>>> >> - Scope consists in a set of object stores that the transaction 
>>> >> operates
>>> >> on.
>>> >> - A connection may have zero or one active transactions.
>>> >> - There may not be any overlap among the scopes of all active
>>> >> transactions (static or dynamic) in a given database. So you cannot
>>> >> have two READ_ONLY static transactions operating simultaneously over
>>> >> the same object store.
>>> >> - The granularity of locking for dynamic transactions is not 
>>> >> specified
>>> >> (all the spec says about this is "do not acquire locks on any 
>>> >> database
>>> >> objects now. Locks are obtained as the application attempts to access
>>> >> those objects").
>>> >> - Using dynamic transactions can lead to dealocks.
>>> >>
>>> >> Given the changes in 9975, here's what I think the spec should say 
>>> >> for
>>> >> now:
>>> >>
>>> >> - There can be multiple active static transactions, as long as their
>>> >> scopes do not overlap, or the overlapping objects are locked in modes
>>> >> that are not mutually exclusive.
>>> >> - [If we decide to keep dynamic transactions] There can be multiple
>>> >> active dynamic transactions. TODO: Decide what to do if they start
>>> >> overlapping:
>>> >>   -- proceed anyway and then fail at commit time in case of
>>> >> conflicts. However, I think this would require implementing MVCC, so
>>> >> implementations that use SQLite would be in trouble?
>>> >
>>> > Such implementations could just lock more conservatively (i.e. not 
>>> > allow
>>> > other transactions during a dynamic transaction).
>>> >
>>>  Umm, I am not sure how useful dynamic transactions would be in that
>>>  case...Ben Turner made the same comment earlier in the thread and I
>>>  agree with him.
>>> 
>>>  Yes, dynamic transactions would not be useful on those 
>>>  implementations, but the point is that you could still implement the 
>>>  spec without a MVCC backend--though it >> would limit the concurrency 
>>>  that's possible.  Thus "implementations that use SQLite would" NOT 
>>>  necessarily "be in trouble".
>>> >>
>>> >> Interesting, I'm glad this conversation came up so we can sync up on 
>>> >> assumptions...mine where:
>>> >> - There can be multiple transactions of any kind active against a given 
>>> >> database session (see note below)
>>> >> - Multiple static transactions may overlap as long as they have 
>>> >> compatible modes, which in practice means they are all READ_ONLY
>>> >> - Dynamic transactions have arbitrary granularity for scope 
>>> >> (implementation specific, down to row-level locking/scope)
>>> >
>>> > Dynamic transactions should be able to lock as little as necessary and as 
>>> > late as required.
>>>
>>> So dynamic transactions, as defined in your proposal, didn't lock on a
>>> whole-objectStore level? If so, how does the author specify which rows
>>> are locked? And why is then openObjectStore a asynchronous operation
>>> that could possibly fail, since at the time when openObjectStore is
>>> called, the implementation doesn't know which rows are going to be
>>> accessed and so can't determine if a deadlock is occurring? And is it
>>> only possible to lock existing rows, or can you prevent new records
>>> from being created? And is it possible to only use read-locking for
>>> some rows, but write-locking for others, in the same objectStore?
>
> That's my interpretation, dynamic transactions don't lock whole object 
> stores. To me dynamic transactions are the same as what typical SQL databases 
> do today.
>
> The author doesn't explicitly specify which rows to lock. All rows that you 
> "see" become locked (e.g. through get(), put(), scanning with a cursor, 
> etc.). If you start the transaction as read-only then they'll all have shared 
> loc

RE: [IndexedDB] Current editor's draft

2010-07-22 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Thursday, July 22, 2010 11:27 AM

>> On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta  wrote:
>> >
>> > On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>> >
>> >>
>> >> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy 
>> >> Orlow
>> >> Sent: Thursday, July 15, 2010 8:41 AM
>> >>
>> >> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  
>> >> wrote:
>> >> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
>> >>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  
>> >>> wrote:
>> 
>>  On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  
>>  wrote:
>>  Nikunj, could you clarify how locking works for the dynamic
>>  transactions proposal that is in the spec draft right now?
>> >>>
>> >>> I'd definitely like to hear what Nikunj originally intended here.
>> 
>> >>
>> >> Hmm, after re-reading the current spec, my understanding is that:
>> >>
>> >> - Scope consists in a set of object stores that the transaction 
>> >> operates
>> >> on.
>> >> - A connection may have zero or one active transactions.
>> >> - There may not be any overlap among the scopes of all active
>> >> transactions (static or dynamic) in a given database. So you cannot
>> >> have two READ_ONLY static transactions operating simultaneously over
>> >> the same object store.
>> >> - The granularity of locking for dynamic transactions is not specified
>> >> (all the spec says about this is "do not acquire locks on any database
>> >> objects now. Locks are obtained as the application attempts to access
>> >> those objects").
>> >> - Using dynamic transactions can lead to dealocks.
>> >>
>> >> Given the changes in 9975, here's what I think the spec should say for
>> >> now:
>> >>
>> >> - There can be multiple active static transactions, as long as their
>> >> scopes do not overlap, or the overlapping objects are locked in modes
>> >> that are not mutually exclusive.
>> >> - [If we decide to keep dynamic transactions] There can be multiple
>> >> active dynamic transactions. TODO: Decide what to do if they start
>> >> overlapping:
>> >>   -- proceed anyway and then fail at commit time in case of
>> >> conflicts. However, I think this would require implementing MVCC, so
>> >> implementations that use SQLite would be in trouble?
>> >
>> > Such implementations could just lock more conservatively (i.e. not 
>> > allow
>> > other transactions during a dynamic transaction).
>> >
>>  Umm, I am not sure how useful dynamic transactions would be in that
>>  case...Ben Turner made the same comment earlier in the thread and I
>>  agree with him.
>> 
>>  Yes, dynamic transactions would not be useful on those implementations, 
>>  but the point is that you could still implement the spec without a MVCC 
>>  backend--though it >> would limit the concurrency that's possible.  
>>  Thus "implementations that use SQLite would" NOT necessarily "be in 
>>  trouble".
>> >>
>> >> Interesting, I'm glad this conversation came up so we can sync up on 
>> >> assumptions...mine where:
>> >> - There can be multiple transactions of any kind active against a given 
>> >> database session (see note below)
>> >> - Multiple static transactions may overlap as long as they have 
>> >> compatible modes, which in practice means they are all READ_ONLY
>> >> - Dynamic transactions have arbitrary granularity for scope 
>> >> (implementation specific, down to row-level locking/scope)
>> >
>> > Dynamic transactions should be able to lock as little as necessary and as 
>> > late as required.
>>
>> So dynamic transactions, as defined in your proposal, didn't lock on a
>> whole-objectStore level? If so, how does the author specify which rows
>> are locked? And why is then openObjectStore a asynchronous operation
>> that could possibly fail, since at the time when openObjectStore is
>> called, the implementation doesn't know which rows are going to be
>> accessed and so can't determine if a deadlock is occurring? And is it
>> only possible to lock existing rows, or can you prevent new records
>> from being created? And is it possible to only use read-locking for
>> some rows, but write-locking for others, in the same objectStore?

That's my interpretation, dynamic transactions don't lock whole object stores. 
To me dynamic transactions are the same as what typical SQL databases do today. 

The author doesn't explicitly specify which rows to lock. All rows that you 
"see" become locked (e.g. through get(), put(), scanning with a cursor, etc.). 
If you start the transaction as read-only then they'll all have shared locks. 
If you start the transaction as read-write then we can choose whether the 
implementation should always attempt to take exclusive locks or if it should 
take shared locks on read, and attempt to upgrade

Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Jonas Sicking
On Thu, Jul 22, 2010 at 3:43 AM, Nikunj Mehta  wrote:
>
> On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:
>
>>
>> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy Orlow
>> Sent: Thursday, July 15, 2010 8:41 AM
>>
>> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:
>> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
>>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:

 On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
 Nikunj, could you clarify how locking works for the dynamic
 transactions proposal that is in the spec draft right now?
>>>
>>> I'd definitely like to hear what Nikunj originally intended here.

>>
>> Hmm, after re-reading the current spec, my understanding is that:
>>
>> - Scope consists in a set of object stores that the transaction operates
>> on.
>> - A connection may have zero or one active transactions.
>> - There may not be any overlap among the scopes of all active
>> transactions (static or dynamic) in a given database. So you cannot
>> have two READ_ONLY static transactions operating simultaneously over
>> the same object store.
>> - The granularity of locking for dynamic transactions is not specified
>> (all the spec says about this is "do not acquire locks on any database
>> objects now. Locks are obtained as the application attempts to access
>> those objects").
>> - Using dynamic transactions can lead to dealocks.
>>
>> Given the changes in 9975, here's what I think the spec should say for
>> now:
>>
>> - There can be multiple active static transactions, as long as their
>> scopes do not overlap, or the overlapping objects are locked in modes
>> that are not mutually exclusive.
>> - [If we decide to keep dynamic transactions] There can be multiple
>> active dynamic transactions. TODO: Decide what to do if they start
>> overlapping:
>>   -- proceed anyway and then fail at commit time in case of
>> conflicts. However, I think this would require implementing MVCC, so
>> implementations that use SQLite would be in trouble?
>
> Such implementations could just lock more conservatively (i.e. not allow
> other transactions during a dynamic transaction).
>
 Umm, I am not sure how useful dynamic transactions would be in that
 case...Ben Turner made the same comment earlier in the thread and I
 agree with him.

 Yes, dynamic transactions would not be useful on those implementations, 
 but the point is that you could still implement the spec without a MVCC 
 backend--though it would limit the concurrency that's possible.  Thus 
 "implementations that use SQLite would" NOT necessarily "be in trouble".
>>
>> Interesting, I'm glad this conversation came up so we can sync up on 
>> assumptions...mine where:
>> - There can be multiple transactions of any kind active against a given 
>> database session (see note below)
>> - Multiple static transactions may overlap as long as they have compatible 
>> modes, which in practice means they are all READ_ONLY
>> - Dynamic transactions have arbitrary granularity for scope (implementation 
>> specific, down to row-level locking/scope)
>
> Dynamic transactions should be able to lock as little as necessary and as 
> late as required.

So dynamic transactions, as defined in your proposal, didn't lock on a
whole-objectStore level? If so, how does the author specify which rows
are locked? And why is then openObjectStore a asynchronous operation
that could possibly fail, since at the time when openObjectStore is
called, the implementation doesn't know which rows are going to be
accessed and so can't determine if a deadlock is occurring? And is it
only possible to lock existing rows, or can you prevent new records
from being created? And is it possible to only use read-locking for
some rows, but write-locking for others, in the same objectStore?

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-22 Thread Nikunj Mehta

On Jul 16, 2010, at 5:41 AM, Pablo Castro wrote:

> 
> From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy Orlow
> Sent: Thursday, July 15, 2010 8:41 AM
> 
> On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:
> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
>> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:
>>> 
>>> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
>>> Nikunj, could you clarify how locking works for the dynamic
>>> transactions proposal that is in the spec draft right now?
>> 
>> I'd definitely like to hear what Nikunj originally intended here.
>>> 
> 
> Hmm, after re-reading the current spec, my understanding is that:
> 
> - Scope consists in a set of object stores that the transaction operates
> on.
> - A connection may have zero or one active transactions.
> - There may not be any overlap among the scopes of all active
> transactions (static or dynamic) in a given database. So you cannot
> have two READ_ONLY static transactions operating simultaneously over
> the same object store.
> - The granularity of locking for dynamic transactions is not specified
> (all the spec says about this is "do not acquire locks on any database
> objects now. Locks are obtained as the application attempts to access
> those objects").
> - Using dynamic transactions can lead to dealocks.
> 
> Given the changes in 9975, here's what I think the spec should say for
> now:
> 
> - There can be multiple active static transactions, as long as their
> scopes do not overlap, or the overlapping objects are locked in modes
> that are not mutually exclusive.
> - [If we decide to keep dynamic transactions] There can be multiple
> active dynamic transactions. TODO: Decide what to do if they start
> overlapping:
>   -- proceed anyway and then fail at commit time in case of
> conflicts. However, I think this would require implementing MVCC, so
> implementations that use SQLite would be in trouble?
 
 Such implementations could just lock more conservatively (i.e. not allow
 other transactions during a dynamic transaction).
 
>>> Umm, I am not sure how useful dynamic transactions would be in that
>>> case...Ben Turner made the same comment earlier in the thread and I
>>> agree with him.
>>> 
>>> Yes, dynamic transactions would not be useful on those implementations, but 
>>> the point is that you could still implement the spec without a MVCC 
>>> backend--though it would limit the concurrency that's possible.  Thus 
>>> "implementations that use SQLite would" NOT necessarily "be in trouble".
> 
> Interesting, I'm glad this conversation came up so we can sync up on 
> assumptions...mine where:
> - There can be multiple transactions of any kind active against a given 
> database session (see note below)
> - Multiple static transactions may overlap as long as they have compatible 
> modes, which in practice means they are all READ_ONLY
> - Dynamic transactions have arbitrary granularity for scope (implementation 
> specific, down to row-level locking/scope)

Dynamic transactions should be able to lock as little as necessary and as late 
as required.

> - Overlapping between statically and dynamically scoped transactions follows 
> the same rules as static-static overlaps; they can only overlap on compatible 
> scopes. The only difference is that dynamic transactions may need to block 
> mid-flight until it can grab the resources it needs to proceed.

This is the intention with the timeout interval and asynchronous nature of the 
openObjectStore on a dynamic transaction.

> 
> Note: for some databases having multiple transactions active on a single 
> connection may be an unsupported thing. This could probably be handled in the 
> IndexedDB layer though by using multiple connections under the covers.
> 
> -pablo
> 




RE: [IndexedDB] Current editor's draft

2010-07-15 Thread Pablo Castro

From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy Orlow
Sent: Thursday, July 15, 2010 8:41 AM

On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:
On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:
>>
>> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
>> >> >> Nikunj, could you clarify how locking works for the dynamic
>> >> >> transactions proposal that is in the spec draft right now?
>> >> >
>> >> > I'd definitely like to hear what Nikunj originally intended here.
>> >> >>
>> >>
>> >> Hmm, after re-reading the current spec, my understanding is that:
>> >>
>> >> - Scope consists in a set of object stores that the transaction operates
>> >> on.
>> >> - A connection may have zero or one active transactions.
>> >> - There may not be any overlap among the scopes of all active
>> >> transactions (static or dynamic) in a given database. So you cannot
>> >> have two READ_ONLY static transactions operating simultaneously over
>> >> the same object store.
>> >> - The granularity of locking for dynamic transactions is not specified
>> >> (all the spec says about this is "do not acquire locks on any database
>> >> objects now. Locks are obtained as the application attempts to access
>> >> those objects").
>> >> - Using dynamic transactions can lead to dealocks.
>> >>
>> >> Given the changes in 9975, here's what I think the spec should say for
>> >> now:
>> >>
>> >> - There can be multiple active static transactions, as long as their
>> >> scopes do not overlap, or the overlapping objects are locked in modes
>> >> that are not mutually exclusive.
>> >> - [If we decide to keep dynamic transactions] There can be multiple
>> >> active dynamic transactions. TODO: Decide what to do if they start
>> >> overlapping:
>> >>   -- proceed anyway and then fail at commit time in case of
>> >> conflicts. However, I think this would require implementing MVCC, so
>> >> implementations that use SQLite would be in trouble?
>> >
>> > Such implementations could just lock more conservatively (i.e. not allow
>> > other transactions during a dynamic transaction).
>> >
>> Umm, I am not sure how useful dynamic transactions would be in that
>> case...Ben Turner made the same comment earlier in the thread and I
>> agree with him.
>>
>> Yes, dynamic transactions would not be useful on those implementations, but 
>> the point is that you could still implement the spec without a MVCC 
>> backend--though it would limit the concurrency that's possible.  Thus 
>> "implementations that use SQLite would" NOT necessarily "be in trouble".

Interesting, I'm glad this conversation came up so we can sync up on 
assumptions...mine where:
- There can be multiple transactions of any kind active against a given 
database session (see note below)
- Multiple static transactions may overlap as long as they have compatible 
modes, which in practice means they are all READ_ONLY
- Dynamic transactions have arbitrary granularity for scope (implementation 
specific, down to row-level locking/scope)
- Overlapping between statically and dynamically scoped transactions follows 
the same rules as static-static overlaps; they can only overlap on compatible 
scopes. The only difference is that dynamic transactions may need to block 
mid-flight until it can grab the resources it needs to proceed.

Note: for some databases having multiple transactions active on a single 
connection may be an unsupported thing. This could probably be handled in the 
IndexedDB layer though by using multiple connections under the covers.

-pablo




Re: [IndexedDB] Current editor's draft

2010-07-15 Thread Jeremy Orlow
On Thu, Jul 15, 2010 at 4:30 PM, Andrei Popescu  wrote:

> On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
> > On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu 
> wrote:
> >>
> >> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow 
> wrote:
> >> >> Nikunj, could you clarify how locking works for the dynamic
> >> >> transactions proposal that is in the spec draft right now?
> >> >
> >> > I'd definitely like to hear what Nikunj originally intended here.
> >> >>
> >>
> >> Hmm, after re-reading the current spec, my understanding is that:
> >>
> >> - Scope consists in a set of object stores that the transaction operates
> >> on.
> >> - A connection may have zero or one active transactions.
> >> - There may not be any overlap among the scopes of all active
> >> transactions (static or dynamic) in a given database. So you cannot
> >> have two READ_ONLY static transactions operating simultaneously over
> >> the same object store.
> >> - The granularity of locking for dynamic transactions is not specified
> >> (all the spec says about this is "do not acquire locks on any database
> >> objects now. Locks are obtained as the application attempts to access
> >> those objects").
> >> - Using dynamic transactions can lead to dealocks.
> >>
> >> Given the changes in 9975, here's what I think the spec should say for
> >> now:
> >>
> >> - There can be multiple active static transactions, as long as their
> >> scopes do not overlap, or the overlapping objects are locked in modes
> >> that are not mutually exclusive.
> >> - [If we decide to keep dynamic transactions] There can be multiple
> >> active dynamic transactions. TODO: Decide what to do if they start
> >> overlapping:
> >>   -- proceed anyway and then fail at commit time in case of
> >> conflicts. However, I think this would require implementing MVCC, so
> >> implementations that use SQLite would be in trouble?
> >
> > Such implementations could just lock more conservatively (i.e. not allow
> > other transactions during a dynamic transaction).
> >
>
> Umm, I am not sure how useful dynamic transactions would be in that
> case...Ben Turner made the same comment earlier in the thread and I
> agree with him.
>

Yes, dynamic transactions would not be useful on those implementations, but
the point is that you could still implement the spec without a MVCC
backend--though it would limit the concurrency that's possible.  Thus
"implementations that use SQLite would" NOT necessarily "be in trouble".


> >>
> >>   -- fail with a specific error.
> >
> > To be clear, this means that any async request inside a dynamic
> transaction
> > could fail and the developer would need to handle this.  Given that we're
> > already concerned about users handling errors on commit, I'd definitely
> be
> > weary of requiring such a thing.  But yes, the other option means that
> > implementations need to either lock more conservatively or be able to
> > continue on even if they know failure is certain.
>
> Agreed.
>
> > Btw, is there any reason you talked only about running multiple static or
> > dynamic transactions at once?  As far as I can tell, we should be able to
> > run multiple at the same time as long as a dynamic transaction always
> fails
> > if it tries to access something that a static transaction has locked.
>
> Ah, sorry I wasn't clear: you can certainly have multiple static and
> dynamic at the same time.
>
> Thanks,
> Andrei
>


Re: [IndexedDB] Current editor's draft

2010-07-15 Thread Andrei Popescu
On Thu, Jul 15, 2010 at 3:24 PM, Jeremy Orlow  wrote:
> On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:
>>
>> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
>> >> Nikunj, could you clarify how locking works for the dynamic
>> >> transactions proposal that is in the spec draft right now?
>> >
>> > I'd definitely like to hear what Nikunj originally intended here.
>> >>
>>
>> Hmm, after re-reading the current spec, my understanding is that:
>>
>> - Scope consists in a set of object stores that the transaction operates
>> on.
>> - A connection may have zero or one active transactions.
>> - There may not be any overlap among the scopes of all active
>> transactions (static or dynamic) in a given database. So you cannot
>> have two READ_ONLY static transactions operating simultaneously over
>> the same object store.
>> - The granularity of locking for dynamic transactions is not specified
>> (all the spec says about this is "do not acquire locks on any database
>> objects now. Locks are obtained as the application attempts to access
>> those objects").
>> - Using dynamic transactions can lead to dealocks.
>>
>> Given the changes in 9975, here's what I think the spec should say for
>> now:
>>
>> - There can be multiple active static transactions, as long as their
>> scopes do not overlap, or the overlapping objects are locked in modes
>> that are not mutually exclusive.
>> - [If we decide to keep dynamic transactions] There can be multiple
>> active dynamic transactions. TODO: Decide what to do if they start
>> overlapping:
>>   -- proceed anyway and then fail at commit time in case of
>> conflicts. However, I think this would require implementing MVCC, so
>> implementations that use SQLite would be in trouble?
>
> Such implementations could just lock more conservatively (i.e. not allow
> other transactions during a dynamic transaction).
>

Umm, I am not sure how useful dynamic transactions would be in that
case...Ben Turner made the same comment earlier in the thread and I
agree with him.

>>
>>   -- fail with a specific error.
>
> To be clear, this means that any async request inside a dynamic transaction
> could fail and the developer would need to handle this.  Given that we're
> already concerned about users handling errors on commit, I'd definitely be
> weary of requiring such a thing.  But yes, the other option means that
> implementations need to either lock more conservatively or be able to
> continue on even if they know failure is certain.

Agreed.

> Btw, is there any reason you talked only about running multiple static or
> dynamic transactions at once?  As far as I can tell, we should be able to
> run multiple at the same time as long as a dynamic transaction always fails
> if it tries to access something that a static transaction has locked.

Ah, sorry I wasn't clear: you can certainly have multiple static and
dynamic at the same time.

Thanks,
Andrei



Re: [IndexedDB] Current editor's draft

2010-07-15 Thread Jeremy Orlow
On Thu, Jul 15, 2010 at 3:09 PM, Andrei Popescu  wrote:

> On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
> >> Nikunj, could you clarify how locking works for the dynamic
> >> transactions proposal that is in the spec draft right now?
> >
> > I'd definitely like to hear what Nikunj originally intended here.
> >>
>
> Hmm, after re-reading the current spec, my understanding is that:
>
> - Scope consists in a set of object stores that the transaction operates
> on.
> - A connection may have zero or one active transactions.
> - There may not be any overlap among the scopes of all active
> transactions (static or dynamic) in a given database. So you cannot
> have two READ_ONLY static transactions operating simultaneously over
> the same object store.
> - The granularity of locking for dynamic transactions is not specified
> (all the spec says about this is "do not acquire locks on any database
> objects now. Locks are obtained as the application attempts to access
> those objects").
> - Using dynamic transactions can lead to dealocks.
>
> Given the changes in 9975, here's what I think the spec should say for now:
>
> - There can be multiple active static transactions, as long as their
> scopes do not overlap, or the overlapping objects are locked in modes
> that are not mutually exclusive.
> - [If we decide to keep dynamic transactions] There can be multiple
> active dynamic transactions. TODO: Decide what to do if they start
> overlapping:
>   -- proceed anyway and then fail at commit time in case of
> conflicts. However, I think this would require implementing MVCC, so
> implementations that use SQLite would be in trouble?
>

Such implementations could just lock more conservatively (i.e. not allow
other transactions during a dynamic transaction).


>   -- fail with a specific error.
>

To be clear, this means that any async request inside a dynamic transaction
could fail and the developer would need to handle this.  Given that we're
already concerned about users handling errors on commit, I'd definitely be
weary of requiring such a thing.  But yes, the other option means that
implementations need to either lock more conservatively or be able to
continue on even if they know failure is certain.

Btw, is there any reason you talked only about running multiple static or
dynamic transactions at once?  As far as I can tell, we should be able to
run multiple at the same time as long as a dynamic transaction always fails
if it tries to access something that a static transaction has locked.
 (Which gets us back to the same 2 scenarios that you were asking about for
dynamic transactions).

J


Re: [IndexedDB] Current editor's draft

2010-07-15 Thread Andrei Popescu
On Thu, Jul 15, 2010 at 9:50 AM, Jeremy Orlow  wrote:
> On Thu, Jul 15, 2010 at 2:37 AM, Jonas Sicking  wrote:
>>
>> On Wed, Jul 14, 2010 at 6:05 PM, Pablo Castro
>>  wrote:
>> >
>> > From: Jonas Sicking [mailto:jo...@sicking.cc]
>> > Sent: Wednesday, July 14, 2010 5:43 PM
>> >
>> > On Wed, Jul 14, 2010 at 5:03 PM, Pablo Castro
>> >  wrote:
>> >>
>> >> From: Jonas Sicking [mailto:jo...@sicking.cc]
>> >> Sent: Wednesday, July 14, 2010 12:07 AM
>> >>
>> >
>> >>> I think what I'm struggling with is how dynamic transactions will help
>> >>> since they are still doing whole-objectStore locking. I'm also curious
>> >>> how you envision people dealing with deadlock hazards. Nikunjs
>> >>> examples in the beginning of this thread simply throw up their hands
>> >>> and report an error if there was a deadlock. That is obviously not
>> >>> good enough for an actual application.
>> >>>
>> >>> So in short, looking forward to an example :)
>> >
>> > I'll try to come up with one, although I doubt the code itself will be
>> > very interesting in this particular case. Not sure what you mean by "they
>> > are still doing whole-objectStore locking". The point of dynamic
>> > transactions is that they *don't* lock the whole store, but instead have 
>> > the
>> > freedom to choose the granularity (e.g. you could do row-level locking).
>>
>> My understanding is that the currently specced dynamic transactions
>> are still whole-objectStore.
>
> My understanding is that of Pablo's.  I'm not aware of anything in the spec
> that'd limit you to object-store wide locks.  Whats more, if this were true
> then I'd be _very_ against adding dynamic transactions in v1 since they'd
> offer us very little in turn for a lot of complexity.
> This misunderstanding would definitely explain a lot of confusion within our
> discussions though.  :-)
>
>>
>> Once you call openObjectStore and
>> successfully receive the objectStore through the 'success' event, a
>> lock is held on the whole objectStore until the transaction is
>> committed. No other transaction, dynamic or static, can open the
>> objectStore in the meantime.
>>
>> I base this on the sentence: "There MAY not be any overlap among the
>> scopes of all open connections to a given database" from the spec.
>>
>> But I might be misunderstanding things entirely.
>>
>> Nikunj, could you clarify how locking works for the dynamic
>> transactions proposal that is in the spec draft right now?
>
> I'd definitely like to hear what Nikunj originally intended here.
>>

Hmm, after re-reading the current spec, my understanding is that:

- Scope consists in a set of object stores that the transaction operates on.
- A connection may have zero or one active transactions.
- There may not be any overlap among the scopes of all active
transactions (static or dynamic) in a given database. So you cannot
have two READ_ONLY static transactions operating simultaneously over
the same object store.
- The granularity of locking for dynamic transactions is not specified
(all the spec says about this is "do not acquire locks on any database
objects now. Locks are obtained as the application attempts to access
those objects").
- Using dynamic transactions can lead to dealocks.

Given the changes in 9975, here's what I think the spec should say for now:

- There can be multiple active static transactions, as long as their
scopes do not overlap, or the overlapping objects are locked in modes
that are not mutually exclusive.
- [If we decide to keep dynamic transactions] There can be multiple
active dynamic transactions. TODO: Decide what to do if they start
overlapping:
   -- proceed anyway and then fail at commit time in case of
conflicts. However, I think this would require implementing MVCC, so
implementations that use SQLite would be in trouble?
   -- fail with a specific error.

Thanks,
Andrei



Re: [IndexedDB] Current editor's draft

2010-07-15 Thread Jeremy Orlow
On Thu, Jul 15, 2010 at 2:37 AM, Jonas Sicking  wrote:

> On Wed, Jul 14, 2010 at 6:05 PM, Pablo Castro
>  wrote:
> >
> > From: Jonas Sicking [mailto:jo...@sicking.cc]
> > Sent: Wednesday, July 14, 2010 5:43 PM
> >
> > On Wed, Jul 14, 2010 at 5:03 PM, Pablo Castro
> >  wrote:
> >>
> >> From: Jonas Sicking [mailto:jo...@sicking.cc]
> >> Sent: Wednesday, July 14, 2010 12:07 AM
> >>
> >
> >>> I think what I'm struggling with is how dynamic transactions will help
> >>> since they are still doing whole-objectStore locking. I'm also curious
> >>> how you envision people dealing with deadlock hazards. Nikunjs
> >>> examples in the beginning of this thread simply throw up their hands
> >>> and report an error if there was a deadlock. That is obviously not
> >>> good enough for an actual application.
> >>>
> >>> So in short, looking forward to an example :)
> >
> > I'll try to come up with one, although I doubt the code itself will be
> very interesting in this particular case. Not sure what you mean by "they
> are still doing whole-objectStore locking". The point of dynamic
> transactions is that they *don't* lock the whole store, but instead have the
> freedom to choose the granularity (e.g. you could do row-level locking).
>
> My understanding is that the currently specced dynamic transactions
> are still whole-objectStore.


My understanding is that of Pablo's.  I'm not aware of anything in the spec
that'd limit you to object-store wide locks.  Whats more, if this were true
then I'd be _very_ against adding dynamic transactions in v1 since they'd
offer us very little in turn for a lot of complexity.

This misunderstanding would definitely explain a lot of confusion within our
discussions though.  :-)


> Once you call openObjectStore and
> successfully receive the objectStore through the 'success' event, a
> lock is held on the whole objectStore until the transaction is
> committed. No other transaction, dynamic or static, can open the
> objectStore in the meantime.
>
> I base this on the sentence: "There MAY not be any overlap among the
> scopes of all open connections to a given database" from the spec.
>
> But I might be misunderstanding things entirely.
>
> Nikunj, could you clarify how locking works for the dynamic
> transactions proposal that is in the spec draft right now?
>

I'd definitely like to hear what Nikunj originally intended here.

 > As for deadlocks, whenever you're doing an operation you need to be ready
> to handle errors (out of disk, timeout, etc.). I'm not sure why deadlocks
> are different. If the underlying implementation has deadlock detection then
> you may get a specific error, otherwise you'll just get a timeout.
>
> Well, I agree that while you have to handle errors to prevent
> dataloss, I suspect that most authors won't. Thus the more error
> conditions that we introduce, the more
>
> I think the difference is that deadlocks will happen often enough that
> they are a real concern. Out of disk space makes most desktop
> applications freak out enough that they generally cause dataloss, thus
> OSs tend to warn when you're running low on disk space.
>
> As for timeouts, I think we should make the defaults not be to have a
> timeout. Only if authors specifically specify a timeout parameter
> should we use one.
>
> My main line of thinking is that authors are going to generally be
> very bad at even looking for errors. Even less so at successfully
> handling those errors in a way that is satisfactory for the user. So I
> think the default behavior is that any time an error occurs, we'll end
> up rolling back the transaction and there will be dataloss.
>
> We should absolutely still provide good error handling opportunities
> so that authors can at least try to deal with it. However I'm not too
> optimistic that people will actually use them correctly.
>

I agree with all of this.

I'd also like to note that, as far as I can tell, without dynamic
transactions there's no possible way to deadlock.  And even with dynamic
transactions, it should be possible to implement things in a way that static
transactions always "win".  Which I think would be a good idea to ensure
that anyone using them gets the simplest possible API.


> >>> >>> This will likely be extra bad for transactions where no write
> >>> >>> operations are done. In this case failure to call a 'commit()'
> >>> >>> function won't result in any broken behavior. The transaction will
> >>> >>> just sit open for a long time and eventually "rolled back", though
> >>> >>> since no changes were done, the rollback is transparent, and the
> only
> >>> >>> noticeable effect is that the application halts for a while while
> the
> >>> >>> transaction is waiting to time out.
> >>> >>>
> >>> >>> I should add that the WebSQLDatabase uses automatically committing
> >>> >>> transactions very similar to what we're proposing, and it seems to
> >>> >>> have worked fine there.
> >>> >
> >>> > I find this a bit scary, although it could be that I'm p

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jonas Sicking
On Wed, Jul 14, 2010 at 6:05 PM, Pablo Castro
 wrote:
>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Wednesday, July 14, 2010 5:43 PM
>
> On Wed, Jul 14, 2010 at 5:03 PM, Pablo Castro
>  wrote:
>>
>> From: Jonas Sicking [mailto:jo...@sicking.cc]
>> Sent: Wednesday, July 14, 2010 12:07 AM
>>
>
>>> I think what I'm struggling with is how dynamic transactions will help
>>> since they are still doing whole-objectStore locking. I'm also curious
>>> how you envision people dealing with deadlock hazards. Nikunjs
>>> examples in the beginning of this thread simply throw up their hands
>>> and report an error if there was a deadlock. That is obviously not
>>> good enough for an actual application.
>>>
>>> So in short, looking forward to an example :)
>
> I'll try to come up with one, although I doubt the code itself will be very 
> interesting in this particular case. Not sure what you mean by "they are 
> still doing whole-objectStore locking". The point of dynamic transactions is 
> that they *don't* lock the whole store, but instead have the freedom to 
> choose the granularity (e.g. you could do row-level locking).

My understanding is that the currently specced dynamic transactions
are still whole-objectStore. Once you call openObjectStore and
successfully receive the objectStore through the 'success' event, a
lock is held on the whole objectStore until the transaction is
committed. No other transaction, dynamic or static, can open the
objectStore in the meantime.

I base this on the sentence: "There MAY not be any overlap among the
scopes of all open connections to a given database" from the spec.

But I might be misunderstanding things entirely.

Nikunj, could you clarify how locking works for the dynamic
transactions proposal that is in the spec draft right now?

> As for deadlocks, whenever you're doing an operation you need to be ready to 
> handle errors (out of disk, timeout, etc.). I'm not sure why deadlocks are 
> different. If the underlying implementation has deadlock detection then you 
> may get a specific error, otherwise you'll just get a timeout.

Well, I agree that while you have to handle errors to prevent
dataloss, I suspect that most authors won't. Thus the more error
conditions that we introduce, the more

I think the difference is that deadlocks will happen often enough that
they are a real concern. Out of disk space makes most desktop
applications freak out enough that they generally cause dataloss, thus
OSs tend to warn when you're running low on disk space.

As for timeouts, I think we should make the defaults not be to have a
timeout. Only if authors specifically specify a timeout parameter
should we use one.

My main line of thinking is that authors are going to generally be
very bad at even looking for errors. Even less so at successfully
handling those errors in a way that is satisfactory for the user. So I
think the default behavior is that any time an error occurs, we'll end
up rolling back the transaction and there will be dataloss.

We should absolutely still provide good error handling opportunities
so that authors can at least try to deal with it. However I'm not too
optimistic that people will actually use them correctly.

>>> >>> This will likely be extra bad for transactions where no write
>>> >>> operations are done. In this case failure to call a 'commit()'
>>> >>> function won't result in any broken behavior. The transaction will
>>> >>> just sit open for a long time and eventually "rolled back", though
>>> >>> since no changes were done, the rollback is transparent, and the only
>>> >>> noticeable effect is that the application halts for a while while the
>>> >>> transaction is waiting to time out.
>>> >>>
>>> >>> I should add that the WebSQLDatabase uses automatically committing
>>> >>> transactions very similar to what we're proposing, and it seems to
>>> >>> have worked fine there.
>>> >
>>> > I find this a bit scary, although it could be that I'm permanently 
>>> > tainted with traditional database stuff. Typical databases follow a 
>>> > presumed abort protocol, where if your code is interrupted by an 
>>> > exception, a process crash or whatever, you can always assume 
>>> > transactions will be rolled back if you didn't reach an explicit call to 
>>> > commit. The implicit commit here takes that away, and I'm not sure how 
>>> > safe that is.
>>> >
>>> > For example, if I don't have proper exception handling in place, an 
>>> > illegal call to some other non-indexeddb related API may throw an 
>>> > exception causing the whole thing to unwind, at which point nothing will 
>>> > be pending to do in the database and thus the currently active 
>>> > transaction will be committed.
>>> >
>>> > Using the same line of thought we used for READ_ONLY, forgetting to call 
>>> > commit() is easy to detect the first time you try out your code. Your 
>>> > changes will simply not stick. It's not as clear as the READ_ONLY example 
>>> > because there is no opportuni

RE: [IndexedDB] Current editor's draft

2010-07-14 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Wednesday, July 14, 2010 5:43 PM

On Wed, Jul 14, 2010 at 5:03 PM, Pablo Castro
 wrote:
>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Wednesday, July 14, 2010 12:07 AM
>

>> I think what I'm struggling with is how dynamic transactions will help
>> since they are still doing whole-objectStore locking. I'm also curious
>> how you envision people dealing with deadlock hazards. Nikunjs
>> examples in the beginning of this thread simply throw up their hands
>> and report an error if there was a deadlock. That is obviously not
>> good enough for an actual application.
>>
>> So in short, looking forward to an example :)

I'll try to come up with one, although I doubt the code itself will be very 
interesting in this particular case. Not sure what you mean by "they are still 
doing whole-objectStore locking". The point of dynamic transactions is that 
they *don't* lock the whole store, but instead have the freedom to choose the 
granularity (e.g. you could do row-level locking). 

As for deadlocks, whenever you're doing an operation you need to be ready to 
handle errors (out of disk, timeout, etc.). I'm not sure why deadlocks are 
different. If the underlying implementation has deadlock detection then you may 
get a specific error, otherwise you'll just get a timeout. 

>> >>> This will likely be extra bad for transactions where no write
>> >>> operations are done. In this case failure to call a 'commit()'
>> >>> function won't result in any broken behavior. The transaction will
>> >>> just sit open for a long time and eventually "rolled back", though
>> >>> since no changes were done, the rollback is transparent, and the only
>> >>> noticeable effect is that the application halts for a while while the
>> >>> transaction is waiting to time out.
>> >>>
>> >>> I should add that the WebSQLDatabase uses automatically committing
>> >>> transactions very similar to what we're proposing, and it seems to
>> >>> have worked fine there.
>> >
>> > I find this a bit scary, although it could be that I'm permanently tainted 
>> > with traditional database stuff. Typical databases follow a presumed abort 
>> > protocol, where if your code is interrupted by an exception, a process 
>> > crash or whatever, you can always assume transactions will be rolled back 
>> > if you didn't reach an explicit call to commit. The implicit commit here 
>> > takes that away, and I'm not sure how safe that is.
>> >
>> > For example, if I don't have proper exception handling in place, an 
>> > illegal call to some other non-indexeddb related API may throw an 
>> > exception causing the whole thing to unwind, at which point nothing will 
>> > be pending to do in the database and thus the currently active transaction 
>> > will be committed.
>> >
>> > Using the same line of thought we used for READ_ONLY, forgetting to call 
>> > commit() is easy to detect the first time you try out your code. Your 
>> > changes will simply not stick. It's not as clear as the READ_ONLY example 
>> > because there is no opportunity to throw an explicit exception with an 
>> > explanation, but the data not being around will certainly prompt 
>> > developers to look for the issue :)

>> Ah, I see where we are differing in thinking. My main concern has been
>> that of rollbacks, and associated dataloss, in the non-error case. For
>> example people forget to call commit() in some branch of their code,
>> thus causing dataloss when the transaction is rolled back.
>>
>> Your concern seems to be that of lack of rollback in the error case,
>> for example when an exception is thrown and not caught somewhere in
>> the code. In this case you'd want to have the transaction rolled back.
>>
>> One way to handle this is to try to detect unhandled errors and
>> implicitly roll back the transaction. Two situations where we could do
>> this is:
>> 1. When an 'error' event is fired, but where .preventDefault() has is
>> not called by any handler. The result is that if an error is ever
>> fired, but no one explicitly handles it, we roll back the transaction.
>> See also below.
>> 2. When a success handler is called, but the handler throws an exception.
>>
>> The second is a bit of a problem from a spec point of view. I'm not
>> sure it is allowed by the DOM Events spec, or by all existing DOM
>> Events implementations. I do still think we can pull it off though.
>> This is something I've been thinking about raising for a while, but I
>> wanted to nail down the raised issues first.
>>
>> Would you feel more comfortable with implicit commits if we did the above?

It does make it better, although this seems to introduce quite moving parts to 
the process. I still think an explicit commit() would be better, but I'm open 
to explore more options.

>> >>> And as you say, you still usually need error callbacks. In fact, we
>> >>> have found while writing examples using our implementation, that you
>> >>> almost always want to ad

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jonas Sicking
On Wed, Jul 14, 2010 at 5:03 PM, Pablo Castro
 wrote:
>
> From: Jonas Sicking [mailto:jo...@sicking.cc]
> Sent: Wednesday, July 14, 2010 12:07 AM
>
>>> > Dynamic transactions:
>>> > I see that most folks would like to see these going away. While I like 
>>> > the predictability and simplifications that we're able to make by using 
>>> > static scopes for transactions, I worry that we'll close the door for two 
>>> > scenarios: background tasks and query processors. Background tasks such 
>>> > as synchronization and post-processing of content would seem to be almost 
>>> > impossible with the static scope approach, mostly due to the granularity 
>>> > of the scope specification (whole stores). Are we okay with saying that 
>>> > you can't for example sync something in the background (e.g. in a worker) 
>>> > while your app is still working? Am I missing something that would enable 
>>> > this class of scenarios? Query processors are also tricky because you 
>>> > usually take the query specification in some form after the transaction 
>>> > started (especially if you want to execute multiple queries with later 
>>> > queries depending on the outcome of the previous ones). The background 
>>> > tasks issue in particular looks pretty painful to me if we don't have a 
>>> > way to achieve it without freezing the application while it happens.
>
>>> I don't understand enough of the details here to be able to make a
>>> decision. The use cases you are bringing up I definitely agree are
>>> important, but I would love to look at even a rough draft of what code
>>> you are expecting people will need to write.
>
> I'll try and hack up and example. In general any scenario that has a worker 
> and the UI thread working on the same database will be quite a challenge, 
> because the worker will have to a) split the work in small pieces, even if it 
> was naturally a bigger chunk and b) consider interleaving implications with 
> the UI thread, otherwise even when split in chunks you're not guaranteed that 
> one of the two will starve the other one (the worker running on a tight loop 
> will effectively always have an active transaction, it'll be just changing 
> the actual transaction from time to time). This can certainly happen with 
> dynamic transactions as well, the only difference is that since the locking 
> granularity is different, it may be that what you're working on in the worker 
> and in the UI threads is independent enough that they don't interfere too 
> much, allowing for some more concurrency.

I think what I'm struggling with is how dynamic transactions will help
since they are still doing whole-objectStore locking. I'm also curious
how you envision people dealing with deadlock hazards. Nikunjs
examples in the beginning of this thread simply throw up their hands
and report an error if there was a deadlock. That is obviously not
good enough for an actual application.

So in short, looking forward to an example :)

>>> > Implicit commit:
>>> > Does this really work? I need to play with sample app code more, it may 
>>> > just be that I'm old-fashioned. For example, if I'm downloading a bunch 
>>> > of data form somewhere and pushing rows into the store within a 
>>> > transaction, wouldn't it be reasonable to do the whole thing in a 
>>> > transaction? In that case I'm likely to have to unwind while I wait for 
>>> > the next callback from XmlHttpRequest with the next chunk of data.
>
>>> You definitely want to do it in a transaction. In our proposal there
>>> is no way to even call .get or .put if you aren't inside a
>>> transaction. For the case you are describing, you'd download the data
>>> using XMLHttpRequest first. Once the data has been downloaded you
>>> start a transaction, parse the data, and make the desired
>>> modifications. Once that is done the transaction is automatically
>>> committed.
>>>
>>> The idea here is to avoid keeping transactions open for long periods
>>> of time, while at the same time making the API easier to work with.
>>> I'm very concerned that any API that requires people to do:
>>>
>>> startOperation();
>>>... do lots of stuff here ...
>>> endOperation();
>>>
>>> people will forget to do the endOperation call. This is especially
>>> true if the startOperation/endOperation calls are spread out over
>>> multiple different asynchronously called functions, which seems to be
>>> the use case you're concerned about above. One very easy way to
>>> "forget" to call endOperation is if something inbetween the two
>>> function calls throw an exception.
>
> Fair enough, maybe I need to think of this scenario differently, and if 
> someone needs to download a bunch of data and then put it in the database 
> atomically the right way is to download to work tables first over a long time 
> and independent transactions, and then use a transaction only to move the 
> data around into its final spot.

Yeah, I think that this is what we want to encourage.

>>> This will likely be extra b

RE: [IndexedDB] Current editor's draft

2010-07-14 Thread Pablo Castro

From: jor...@google.com [mailto:jor...@google.com] On Behalf Of Jeremy Orlow
Sent: Wednesday, July 14, 2010 12:10 AM

On Wed, Jul 14, 2010 at 3:52 AM, Pablo Castro  
wrote:

From: public-webapps-requ...@w3.org [mailto:public-webapps-requ...@w3.org] On 
Behalf Of Andrei Popescu
Sent: Monday, July 12, 2010 5:23 AM

>> >> Dynamic transactions:
>> >> I see that most folks would like to see these going away. While I like 
>> >> the predictability and simplifications that we're able to make by using 
>> >> static scopes for transactions, I worry that we'll close the door for two 
>> >> scenarios: background tasks and query processors. Background tasks such 
>> >> as synchronization and post-processing of content would seem to be almost 
>> >> impossible with the static scope approach, mostly due to the granularity 
>> >> of the scope specification (whole stores). Are we okay with saying that 
>> >> you can't for example sync something in the background (e.g. in a worker) 
>> >> while your app is still working? Am I missing something that would enable 
>> >> this class of scenarios? Query processors are also tricky because you 
>> >> usually take the query specification in some form after the transaction 
>> >> started (especially if you want to execute multiple queries with later 
>> >> queries depending on the outcome of the previous ones). The background 
>> >> tasks issue in particular looks pretty painful to me if we don't have a 
>> >> way to achieve it without freezing the application while it happens.

>> Well, the application should never freeze in terms of the UI locking up, but 
>> in what you described I could see it taking a while for data to show up on 
>> the screen.  This is something that can be fixed by doing smaller updates on 
>> the background thread, sending a message to the background thread that it 
>> should abort for now, doing all database access on the background thread, 
>> etc.

This is an issue regardless, isn't it? Let's say you have a worker churning on 
the database somehow. The worker has no UI or user to wait for, so it'll run in 
a tight loop at full speed. If it splits the work in small transactions, in 
cases where it doesn't have to wait for something external there will still be 
a small gap between transactions. That could easily starve the UI thread that 
needs to find an opportunity to get in and do a quick thing against the 
database. As you say the difference between freezing and locking up at this 
point is not that critical, as the end user in the end is just waiting.

>> One point that I never saw made in the thread that I think is really 
>> important is that dynamic transactions can make concurrency worse in some 
>> cases.  For example, with dynamic transactions you can get into live-lock 
>> situations.  Also, using Pablo's example, you could easily get into a 
>> situation where the long running transaction on the worker keeps hitting 
>> serialization issues and thus it's never able to make progress.

While it could certainly happen, I don't remember seeing something like a 
live-lock in a long, long time. Deadlocks are common, but a simple timeout will 
kill one of the transactions and let the other make progress. A bit violent, 
but always effective. 

>> I do see that there are use cases where having dynamic transactions would be 
>> much nicer, but the amount of non-determinism they add (including to 
>> performance) has me pretty worried.  I pretty firmly believe we should look 
>> into adding them in v2 and remove them for now.  If we do leave them in, it 
>> should definitely be in its own method to make it quite clear that the 
>> semantics are more complex.
 
Let's explore a bit more and see where we land. I'm not pushing for dynamic 
transactions themselves, but more for the scenarios they enable (background 
processing and such). If we find other ways of doing that, then all the better. 
Having different entry points is reasonable.

>> >> Nested transactions:
>> >> Not sure why we're considering this an advanced scenario. To be clear 
>> >> about what the feature means to me: make it legal to start a transaction 
>> >> when one is already in progress, and the nested one is effectively a 
>> >> no-op, just refcounts the transaction, so you need equal amounts of 
>> >> commit()'s, implicit or explicit, and an abort() cancels all nested 
>> >> transactions. The purpose of this is to allow composition, where a piece 
>> >> of code that needs a transaction can start one locally, independently of 
>> >> whether the caller had already one going.

>> I believe it's actually a bit more tricky than what you said.  For example, 
>> if we only support static transactions, will we require that any nested 
>> transaction only request a subset of the locks the outer one took?  What if 
>> we try to start a dynamic transaction inside of a static one?  Etc.  But I 
>> agree it's not _that_ tricky and I'm also not convinced it's an "advanced" 
>> feature.

>> I'd s

RE: [IndexedDB] Current editor's draft

2010-07-14 Thread Pablo Castro

From: Jonas Sicking [mailto:jo...@sicking.cc] 
Sent: Wednesday, July 14, 2010 12:07 AM

>> > Dynamic transactions:
>> > I see that most folks would like to see these going away. While I like the 
>> > predictability and simplifications that we're able to make by using static 
>> > scopes for transactions, I worry that we'll close the door for two 
>> > scenarios: background tasks and query processors. Background tasks such as 
>> > synchronization and post-processing of content would seem to be almost 
>> > impossible with the static scope approach, mostly due to the granularity 
>> > of the scope specification (whole stores). Are we okay with saying that 
>> > you can't for example sync something in the background (e.g. in a worker) 
>> > while your app is still working? Am I missing something that would enable 
>> > this class of scenarios? Query processors are also tricky because you 
>> > usually take the query specification in some form after the transaction 
>> > started (especially if you want to execute multiple queries with later 
>> > queries depending on the outcome of the previous ones). The background 
>> > tasks issue in particular looks pretty painful to me if we don't have a 
>> > way to achieve it without freezing the application while it happens.

>> I don't understand enough of the details here to be able to make a
>> decision. The use cases you are bringing up I definitely agree are
>> important, but I would love to look at even a rough draft of what code
>> you are expecting people will need to write.

I'll try and hack up and example. In general any scenario that has a worker and 
the UI thread working on the same database will be quite a challenge, because 
the worker will have to a) split the work in small pieces, even if it was 
naturally a bigger chunk and b) consider interleaving implications with the UI 
thread, otherwise even when split in chunks you're not guaranteed that one of 
the two will starve the other one (the worker running on a tight loop will 
effectively always have an active transaction, it'll be just changing the 
actual transaction from time to time). This can certainly happen with dynamic 
transactions as well, the only difference is that since the locking granularity 
is different, it may be that what you're working on in the worker and in the UI 
threads is independent enough that they don't interfere too much, allowing for 
some more concurrency.

>> What I suggest is that we keep dynamic transactions in the spec for
>> now, but separate the API from static transactions, start a separate
>> thread and try to hammer out the details and see what we arrive at. I
>> do want to clarify that I don't think dynamic transactions are
>> particularly hard to implement, I just suspect they are hard to use
>> correctly.

Sounds reasonable.

>> > Implicit commit:
>> > Does this really work? I need to play with sample app code more, it may 
>> > just be that I'm old-fashioned. For example, if I'm downloading a bunch of 
>> > data form somewhere and pushing rows into the store within a transaction, 
>> > wouldn't it be reasonable to do the whole thing in a transaction? In that 
>> > case I'm likely to have to unwind while I wait for the next callback from 
>> > XmlHttpRequest with the next chunk of data.

>> You definitely want to do it in a transaction. In our proposal there
>> is no way to even call .get or .put if you aren't inside a
>> transaction. For the case you are describing, you'd download the data
>> using XMLHttpRequest first. Once the data has been downloaded you
>> start a transaction, parse the data, and make the desired
>> modifications. Once that is done the transaction is automatically
>> committed.
>>
>> The idea here is to avoid keeping transactions open for long periods
>> of time, while at the same time making the API easier to work with.
>> I'm very concerned that any API that requires people to do:
>>
>> startOperation();
>>... do lots of stuff here ...
>> endOperation();
>>
>> people will forget to do the endOperation call. This is especially
>> true if the startOperation/endOperation calls are spread out over
>> multiple different asynchronously called functions, which seems to be
>> the use case you're concerned about above. One very easy way to
>> "forget" to call endOperation is if something inbetween the two
>> function calls throw an exception.

Fair enough, maybe I need to think of this scenario differently, and if someone 
needs to download a bunch of data and then put it in the database atomically 
the right way is to download to work tables first over a long time and 
independent transactions, and then use a transaction only to move the data 
around into its final spot.

>> This will likely be extra bad for transactions where no write
>> operations are done. In this case failure to call a 'commit()'
>> function won't result in any broken behavior. The transaction will
>> just sit open for a long time and eventually "rolled back", though
>

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jonas Sicking
On Wed, Jul 14, 2010 at 9:28 AM, Andrei Popescu  wrote:
> On Wed, Jul 14, 2010 at 5:21 PM, Jonas Sicking  wrote:
>> On Wed, Jul 14, 2010 at 5:20 AM, Andrei Popescu  wrote:
>>> Hi,
>>>
>>> I would like to propose that we update the current spec to reflect all
>>> the changes we have agreement on. We can then iteratively review and
>>> make edits as soon as the remaining issues are solved.  Concretely, I
>>> would like to check in a fix for
>>>
>>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=9975
>>>
>>> with the following two exceptions which, based on the feedback in this
>>> thread, require more discussion:
>>>
>>> - leave in support for dynamic transactions but add a separate API for
>>> it, as suggested by Jonas earlier in this thread.
>>> - leave in the explicit transaction commit
>>> - leave in nested transactions
>>>
>>> The changes in 9975 have been debated for more than two month now, so
>>> I feel it's about time to update the specification so that it's in
>>> line with what we're actually discussing.
>>
>> When you say "leave in the explicit transaction commit", do you mean
>> in addition to the implicit commit one there are no more requests on a
>> transaction, or instead of it?
>>
>
> In addition. In the current editor draft we have both:
>
> Implicit commit is described at:
> http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#dfn-transaction
>
> Explicit commit is defined at
> http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#widl-IDBTransaction-commit
>
> I was saying I would not remove the explicit one pending further discussion.

Makes sense, thanks for clarifying.

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Andrei Popescu
On Wed, Jul 14, 2010 at 5:21 PM, Jonas Sicking  wrote:
> On Wed, Jul 14, 2010 at 5:20 AM, Andrei Popescu  wrote:
>> Hi,
>>
>> I would like to propose that we update the current spec to reflect all
>> the changes we have agreement on. We can then iteratively review and
>> make edits as soon as the remaining issues are solved.  Concretely, I
>> would like to check in a fix for
>>
>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=9975
>>
>> with the following two exceptions which, based on the feedback in this
>> thread, require more discussion:
>>
>> - leave in support for dynamic transactions but add a separate API for
>> it, as suggested by Jonas earlier in this thread.
>> - leave in the explicit transaction commit
>> - leave in nested transactions
>>
>> The changes in 9975 have been debated for more than two month now, so
>> I feel it's about time to update the specification so that it's in
>> line with what we're actually discussing.
>
> When you say "leave in the explicit transaction commit", do you mean
> in addition to the implicit commit one there are no more requests on a
> transaction, or instead of it?
>

In addition. In the current editor draft we have both:

Implicit commit is described at:
http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#dfn-transaction

Explicit commit is defined at
http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#widl-IDBTransaction-commit

I was saying I would not remove the explicit one pending further discussion.

Thanks,
Andrei



Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jonas Sicking
On Wed, Jul 14, 2010 at 5:20 AM, Andrei Popescu  wrote:
> Hi,
>
> I would like to propose that we update the current spec to reflect all
> the changes we have agreement on. We can then iteratively review and
> make edits as soon as the remaining issues are solved.  Concretely, I
> would like to check in a fix for
>
> http://www.w3.org/Bugs/Public/show_bug.cgi?id=9975
>
> with the following two exceptions which, based on the feedback in this
> thread, require more discussion:
>
> - leave in support for dynamic transactions but add a separate API for
> it, as suggested by Jonas earlier in this thread.
> - leave in the explicit transaction commit
> - leave in nested transactions
>
> The changes in 9975 have been debated for more than two month now, so
> I feel it's about time to update the specification so that it's in
> line with what we're actually discussing.

When you say "leave in the explicit transaction commit", do you mean
in addition to the implicit commit one there are no more requests on a
transaction, or instead of it?

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-14 Thread ben turner
On Wed, Jul 14, 2010 at 3:10 AM, Jeremy Orlow  wrote:
> For example, with dynamic transactions you can get into live-lock
> situations.

I'm particularly opposed to dynamic transactions for just this reason.
We would clearly have to throw an exception or call the error callback
if we detect livelock. I doubt that most web authors would recognize
the potential hazard, and even if they did I think it would be
extremely difficult for a web author to test such a scenario or write
code to handle it properly. The hardware running the web app and the
browser's transaction scheduling algorithm would of course affect the
frequency of these collisions making proper tests even more difficult.

> If we do leave them in, it
> should definitely be in its own method to make it quite clear that the
> semantics are more complex.

I completely agree.

So, as I've said, I'm very opposed to leaving dynamic transactions in
the spec. However, one thing we could do if everyone really wanted
this feature I guess is to set a limit of only a single dynamic
transaction per database at a time. That would remove the livelock
hazard but it may diminish the utility of the feature enough to be
useless.



Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jeremy Orlow
On Wed, Jul 14, 2010 at 1:20 PM, Andrei Popescu  wrote:

> Hi,
>
> I would like to propose that we update the current spec to reflect all
> the changes we have agreement on. We can then iteratively review and
> make edits as soon as the remaining issues are solved.  Concretely, I
> would like to check in a fix for
>
> http://www.w3.org/Bugs/Public/show_bug.cgi?id=9975
>
> with the following two exceptions which, based on the feedback in this
> thread, require more discussion:
>
> - leave in support for dynamic transactions but add a separate API for
> it, as suggested by Jonas earlier in this thread.
> - leave in the explicit transaction commit
> - leave in nested transactions
>
> The changes in 9975 have been debated for more than two month now, so
> I feel it's about time to update the specification so that it's in
> line with what we're actually discussing.
>

Agreed.  In the future I think we should never let things stay this out of
sync for this long, but I understand how this was a bit of a special case
because of the scope of the changes.  But yeah, let's make these changes and
then iterate.  And hopefully we can resolve the dynamic transaction,
explicit commit, and nested transaction issues in the near future.


> Thanks,
> Andrei
>
> On Wed, Jul 14, 2010 at 8:10 AM, Jeremy Orlow  wrote:
> > On Wed, Jul 14, 2010 at 3:52 AM, Pablo Castro <
> pablo.cas...@microsoft.com>
> > wrote:
> >>
> >> From: public-webapps-requ...@w3.org [mailto:
> public-webapps-requ...@w3.org]
> >> On Behalf Of Andrei Popescu
> >> Sent: Monday, July 12, 2010 5:23 AM
> >>
> >> Sorry I disappeared for a while. Catching up with this discussion was an
> >> interesting exercise...
> >
> > Yes, Indeed.  :-)
> >
> >>
> >> there is no particular message in this thread I can respond to, so I
> >> thought I'd just reply to the last one.
> >
> > Probably a good idea.  I was trying to respond hixie style--which is
> harder
> > than it looks on stuff like this.
> >
> >>
> >> Overall I think the new proposal is shaping up well and is being
> effective
> >> in simplifying scenarios. I do have a few suggestions and questions for
> >> things I'm not sure I see all the way.
> >>
> >> READ_ONLY vs READ_WRITE as defaults for transactions:
> >> To be perfectly honest, I think this discussion went really deep over an
> >> issue that won't be a huge deal for most people. My perspective, trying
> to
> >> avoid performance or usage frequency speculation, is around what's
> easier to
> >> detect. Concurrency issues are hard to see. On the other hand, whenever
> we
> >> can throw an exception and give explicit guidance that unblocks people
> right
> >> away. For this case I suspect it's best to default to READ_ONLY, because
> if
> >> someone doesn't read or think about it and just uses the stuff and tries
> to
> >> change something they'll get a clear error message saying "if you want
> to
> >> change stuff, use READ_WRITE please". The error is not data- or
> >> context-dependent, so it'll fail on first try at most once per developer
> and
> >> once they fix it they'll know for all future cases.
> >
> > Couldn't have said it better myself.
> >
> >>
> >> Dynamic transactions:
> >> I see that most folks would like to see these going away. While I like
> the
> >> predictability and simplifications that we're able to make by using
> static
> >> scopes for transactions, I worry that we'll close the door for two
> >> scenarios: background tasks and query processors. Background tasks such
> as
> >> synchronization and post-processing of content would seem to be almost
> >> impossible with the static scope approach, mostly due to the granularity
> of
> >> the scope specification (whole stores). Are we okay with saying that you
> >> can't for example sync something in the background (e.g. in a worker)
> while
> >> your app is still working? Am I missing something that would enable this
> >> class of scenarios? Query processors are also tricky because you usually
> >> take the query specification in some form after the transaction started
> >> (especially if you want to execute multiple queries with later queries
> >> depending on the outcome of the previous ones). The background tasks
> issue
> >> in particular looks pretty painful to me if we don't have a way to
> achieve
> >> it without freezing the application while it happens.
> >
> > Well, the application should never freeze in terms of the UI locking up,
> but
> > in what you described I could see it taking a while for data to show up
> on
> > the screen.  This is something that can be fixed by doing smaller updates
> on
> > the background thread, sending a message to the background thread that it
> > should abort for now, doing all database access on the background thread,
> > etc.
> > One point that I never saw made in the thread that I think is really
> > important is that dynamic transactions can make concurrency worse in some
> > cases.  For example, with dynamic transactions you can get into live-loc

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Andrei Popescu
Hi,

I would like to propose that we update the current spec to reflect all
the changes we have agreement on. We can then iteratively review and
make edits as soon as the remaining issues are solved.  Concretely, I
would like to check in a fix for

http://www.w3.org/Bugs/Public/show_bug.cgi?id=9975

with the following two exceptions which, based on the feedback in this
thread, require more discussion:

- leave in support for dynamic transactions but add a separate API for
it, as suggested by Jonas earlier in this thread.
- leave in the explicit transaction commit
- leave in nested transactions

The changes in 9975 have been debated for more than two month now, so
I feel it's about time to update the specification so that it's in
line with what we're actually discussing.

Thanks,
Andrei

On Wed, Jul 14, 2010 at 8:10 AM, Jeremy Orlow  wrote:
> On Wed, Jul 14, 2010 at 3:52 AM, Pablo Castro 
> wrote:
>>
>> From: public-webapps-requ...@w3.org [mailto:public-webapps-requ...@w3.org]
>> On Behalf Of Andrei Popescu
>> Sent: Monday, July 12, 2010 5:23 AM
>>
>> Sorry I disappeared for a while. Catching up with this discussion was an
>> interesting exercise...
>
> Yes, Indeed.  :-)
>
>>
>> there is no particular message in this thread I can respond to, so I
>> thought I'd just reply to the last one.
>
> Probably a good idea.  I was trying to respond hixie style--which is harder
> than it looks on stuff like this.
>
>>
>> Overall I think the new proposal is shaping up well and is being effective
>> in simplifying scenarios. I do have a few suggestions and questions for
>> things I'm not sure I see all the way.
>>
>> READ_ONLY vs READ_WRITE as defaults for transactions:
>> To be perfectly honest, I think this discussion went really deep over an
>> issue that won't be a huge deal for most people. My perspective, trying to
>> avoid performance or usage frequency speculation, is around what's easier to
>> detect. Concurrency issues are hard to see. On the other hand, whenever we
>> can throw an exception and give explicit guidance that unblocks people right
>> away. For this case I suspect it's best to default to READ_ONLY, because if
>> someone doesn't read or think about it and just uses the stuff and tries to
>> change something they'll get a clear error message saying "if you want to
>> change stuff, use READ_WRITE please". The error is not data- or
>> context-dependent, so it'll fail on first try at most once per developer and
>> once they fix it they'll know for all future cases.
>
> Couldn't have said it better myself.
>
>>
>> Dynamic transactions:
>> I see that most folks would like to see these going away. While I like the
>> predictability and simplifications that we're able to make by using static
>> scopes for transactions, I worry that we'll close the door for two
>> scenarios: background tasks and query processors. Background tasks such as
>> synchronization and post-processing of content would seem to be almost
>> impossible with the static scope approach, mostly due to the granularity of
>> the scope specification (whole stores). Are we okay with saying that you
>> can't for example sync something in the background (e.g. in a worker) while
>> your app is still working? Am I missing something that would enable this
>> class of scenarios? Query processors are also tricky because you usually
>> take the query specification in some form after the transaction started
>> (especially if you want to execute multiple queries with later queries
>> depending on the outcome of the previous ones). The background tasks issue
>> in particular looks pretty painful to me if we don't have a way to achieve
>> it without freezing the application while it happens.
>
> Well, the application should never freeze in terms of the UI locking up, but
> in what you described I could see it taking a while for data to show up on
> the screen.  This is something that can be fixed by doing smaller updates on
> the background thread, sending a message to the background thread that it
> should abort for now, doing all database access on the background thread,
> etc.
> One point that I never saw made in the thread that I think is really
> important is that dynamic transactions can make concurrency worse in some
> cases.  For example, with dynamic transactions you can get into live-lock
> situations.  Also, using Pablo's example, you could easily get into a
> situation where the long running transaction on the worker keeps hitting
> serialization issues and thus it's never able to make progress.
> I do see that there are use cases where having dynamic transactions would be
> much nicer, but the amount of non-determinism they add (including to
> performance) has me pretty worried.  I pretty firmly believe we should look
> into adding them in v2 and remove them for now.  If we do leave them in, it
> should definitely be in its own method to make it quite clear that the
> semantics are more complex.
>
>>
>> Implicit commit:
>> Does this really wo

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jeremy Orlow
On Wed, Jul 14, 2010 at 3:52 AM, Pablo Castro wrote:

>
> From: public-webapps-requ...@w3.org [mailto:public-webapps-requ...@w3.org]
> On Behalf Of Andrei Popescu
> Sent: Monday, July 12, 2010 5:23 AM
>
> Sorry I disappeared for a while. Catching up with this discussion was an
> interesting exercise...


Yes, Indeed.  :-)


> there is no particular message in this thread I can respond to, so I
> thought I'd just reply to the last one.


Probably a good idea.  I was trying to respond hixie style--which is harder
than it looks on stuff like this.


Overall I think the new proposal is shaping up well and is being effective
> in simplifying scenarios. I do have a few suggestions and questions for
> things I'm not sure I see all the way.
>
> READ_ONLY vs READ_WRITE as defaults for transactions:
> To be perfectly honest, I think this discussion went really deep over an
> issue that won't be a huge deal for most people. My perspective, trying to
> avoid performance or usage frequency speculation, is around what's easier to
> detect. Concurrency issues are hard to see. On the other hand, whenever we
> can throw an exception and give explicit guidance that unblocks people right
> away. For this case I suspect it's best to default to READ_ONLY, because if
> someone doesn't read or think about it and just uses the stuff and tries to
> change something they'll get a clear error message saying "if you want to
> change stuff, use READ_WRITE please". The error is not data- or
> context-dependent, so it'll fail on first try at most once per developer and
> once they fix it they'll know for all future cases.
>

Couldn't have said it better myself.


Dynamic transactions:
> I see that most folks would like to see these going away. While I like the
> predictability and simplifications that we're able to make by using static
> scopes for transactions, I worry that we'll close the door for two
> scenarios: background tasks and query processors. Background tasks such as
> synchronization and post-processing of content would seem to be almost
> impossible with the static scope approach, mostly due to the granularity of
> the scope specification (whole stores). Are we okay with saying that you
> can't for example sync something in the background (e.g. in a worker) while
> your app is still working? Am I missing something that would enable this
> class of scenarios? Query processors are also tricky because you usually
> take the query specification in some form after the transaction started
> (especially if you want to execute multiple queries with later queries
> depending on the outcome of the previous ones). The background tasks issue
> in particular looks pretty painful to me if we don't have a way to achieve
> it without freezing the application while it happens.
>

Well, the application should never freeze in terms of the UI locking up, but
in what you described I could see it taking a while for data to show up on
the screen.  This is something that can be fixed by doing smaller updates on
the background thread, sending a message to the background thread that it
should abort for now, doing all database access on the background thread,
etc.

One point that I never saw made in the thread that I think is really
important is that dynamic transactions can make concurrency worse in some
cases.  For example, with dynamic transactions you can get into live-lock
situations.  Also, using Pablo's example, you could easily get into a
situation where the long running transaction on the worker keeps hitting
serialization issues and thus it's never able to make progress.

I do see that there are use cases where having dynamic transactions would be
much nicer, but the amount of non-determinism they add (including to
performance) has me pretty worried.  I pretty firmly believe we should look
into adding them in v2 and remove them for now.  If we do leave them in, it
should definitely be in its own method to make it quite clear that the
semantics are more complex.


Implicit commit:
> Does this really work? I need to play with sample app code more, it may
> just be that I'm old-fashioned. For example, if I'm downloading a bunch of
> data form somewhere and pushing rows into the store within a transaction,
> wouldn't it be reasonable to do the whole thing in a transaction? In that
> case I'm likely to have to unwind while I wait for the next callback from
> XmlHttpRequest with the next chunk of data. I understand that avoiding it
> results in nicer patterns (e.g. db.objectStores("foo").get(123).onsuccess =
> ...), but in practice I'm not sure if that will hold given that you still
> need error callbacks and such.
>

I believe your example of doing XHRs in the middle of a transaction is
something we were explicitly trying to avoid making possible.  In this case,
you should do all of your XHRs first and then do your transaction.  If you
need to read form the ObjectStore, do a XHR, and then write to the
ObjectStore, you can implement it with 2 tr

Re: [IndexedDB] Current editor's draft

2010-07-14 Thread Jonas Sicking
Hi Pablo,

First off, thanks for your comments! (Probably too much) details below.

On Tue, Jul 13, 2010 at 7:52 PM, Pablo Castro
 wrote:
>
> From: public-webapps-requ...@w3.org [mailto:public-webapps-requ...@w3.org] On 
> Behalf Of Andrei Popescu
> Sent: Monday, July 12, 2010 5:23 AM
>
> Sorry I disappeared for a while. Catching up with this discussion was an 
> interesting exercise...there is no particular message in this thread I can 
> respond to, so I thought I'd just reply to the last one. Overall I think the 
> new proposal is shaping up well and is being effective in simplifying 
> scenarios. I do have a few suggestions and questions for things I'm not sure 
> I see all the way.
>
> READ_ONLY vs READ_WRITE as defaults for transactions:
> To be perfectly honest, I think this discussion went really deep over an 
> issue that won't be a huge deal for most people. My perspective, trying to 
> avoid performance or usage frequency speculation, is around what's easier to 
> detect. Concurrency issues are hard to see. On the other hand, whenever we 
> can throw an exception and give explicit guidance that unblocks people right 
> away. For this case I suspect it's best to default to READ_ONLY, because if 
> someone doesn't read or think about it and just uses the stuff and tries to 
> change something they'll get a clear error message saying "if you want to 
> change stuff, use READ_WRITE please". The error is not data- or 
> context-dependent, so it'll fail on first try at most once per developer and 
> once they fix it they'll know for all future cases.

Yup, this was exactly my thinking.

> Dynamic transactions:
> I see that most folks would like to see these going away. While I like the 
> predictability and simplifications that we're able to make by using static 
> scopes for transactions, I worry that we'll close the door for two scenarios: 
> background tasks and query processors. Background tasks such as 
> synchronization and post-processing of content would seem to be almost 
> impossible with the static scope approach, mostly due to the granularity of 
> the scope specification (whole stores). Are we okay with saying that you 
> can't for example sync something in the background (e.g. in a worker) while 
> your app is still working? Am I missing something that would enable this 
> class of scenarios? Query processors are also tricky because you usually take 
> the query specification in some form after the transaction started 
> (especially if you want to execute multiple queries with later queries 
> depending on the outcome of the previous ones). The background tasks issue in 
> particular looks pretty painful to me if we don't have a way to achieve it 
> without freezing the application while it happens.

I don't understand enough of the details here to be able to make a
decision. The use cases you are bringing up I definitely agree are
important, but I would love to look at even a rough draft of what code
you are expecting people will need to write.

What I suggest is that we keep dynamic transactions in the spec for
now, but separate the API from static transactions, start a separate
thread and try to hammer out the details and see what we arrive at. I
do want to clarify that I don't think dynamic transactions are
particularly hard to implement, I just suspect they are hard to use
correctly.

> Implicit commit:
> Does this really work? I need to play with sample app code more, it may just 
> be that I'm old-fashioned. For example, if I'm downloading a bunch of data 
> form somewhere and pushing rows into the store within a transaction, wouldn't 
> it be reasonable to do the whole thing in a transaction? In that case I'm 
> likely to have to unwind while I wait for the next callback from 
> XmlHttpRequest with the next chunk of data.

You definitely want to do it in a transaction. In our proposal there
is no way to even call .get or .put if you aren't inside a
transaction. For the case you are describing, you'd download the data
using XMLHttpRequest first. Once the data has been downloaded you
start a transaction, parse the data, and make the desired
modifications. Once that is done the transaction is automatically
committed.

The idea here is to avoid keeping transactions open for long periods
of time, while at the same time making the API easier to work with.
I'm very concerned that any API that requires people to do:

startOperation();
... do lots of stuff here ...
endOperation();

people will forget to do the endOperation call. This is especially
true if the startOperation/endOperation calls are spread out over
multiple different asynchronously called functions, which seems to be
the use case you're concerned about above. One very easy way to
"forget" to call endOperation is if something inbetween the two
function calls throw an exception.

This will likely be extra bad for transactions where no write
operations are done. In this case failure to call a 'commit()'
function won't result in

RE: [IndexedDB] Current editor's draft

2010-07-13 Thread Pablo Castro

From: public-webapps-requ...@w3.org [mailto:public-webapps-requ...@w3.org] On 
Behalf Of Andrei Popescu
Sent: Monday, July 12, 2010 5:23 AM

Sorry I disappeared for a while. Catching up with this discussion was an 
interesting exercise...there is no particular message in this thread I can 
respond to, so I thought I'd just reply to the last one. Overall I think the 
new proposal is shaping up well and is being effective in simplifying 
scenarios. I do have a few suggestions and questions for things I'm not sure I 
see all the way.

READ_ONLY vs READ_WRITE as defaults for transactions:
To be perfectly honest, I think this discussion went really deep over an issue 
that won't be a huge deal for most people. My perspective, trying to avoid 
performance or usage frequency speculation, is around what's easier to detect. 
Concurrency issues are hard to see. On the other hand, whenever we can throw an 
exception and give explicit guidance that unblocks people right away. For this 
case I suspect it's best to default to READ_ONLY, because if someone doesn't 
read or think about it and just uses the stuff and tries to change something 
they'll get a clear error message saying "if you want to change stuff, use 
READ_WRITE please". The error is not data- or context-dependent, so it'll fail 
on first try at most once per developer and once they fix it they'll know for 
all future cases.

Dynamic transactions:
I see that most folks would like to see these going away. While I like the 
predictability and simplifications that we're able to make by using static 
scopes for transactions, I worry that we'll close the door for two scenarios: 
background tasks and query processors. Background tasks such as synchronization 
and post-processing of content would seem to be almost impossible with the 
static scope approach, mostly due to the granularity of the scope specification 
(whole stores). Are we okay with saying that you can't for example sync 
something in the background (e.g. in a worker) while your app is still working? 
Am I missing something that would enable this class of scenarios? Query 
processors are also tricky because you usually take the query specification in 
some form after the transaction started (especially if you want to execute 
multiple queries with later queries depending on the outcome of the previous 
ones). The background tasks issue in particular looks pretty painful to me if 
we don't have a way to achieve it without freezing the application while it 
happens. 

Implicit commit:
Does this really work? I need to play with sample app code more, it may just be 
that I'm old-fashioned. For example, if I'm downloading a bunch of data form 
somewhere and pushing rows into the store within a transaction, wouldn't it be 
reasonable to do the whole thing in a transaction? In that case I'm likely to 
have to unwind while I wait for the next callback from XmlHttpRequest with the 
next chunk of data. I understand that avoiding it results in nicer patterns 
(e.g. db.objectStores("foo").get(123).onsuccess = ...), but in practice I'm not 
sure if that will hold given that you still need error callbacks and such.

Nested transactions:
Not sure why we're considering this an advanced scenario. To be clear about 
what the feature means to me: make it legal to start a transaction when one is 
already in progress, and the nested one is effectively a no-op, just refcounts 
the transaction, so you need equal amounts of commit()'s, implicit or explicit, 
and an abort() cancels all nested transactions. The purpose of this is to allow 
composition, where a piece of code that needs a transaction can start one 
locally, independently of whether the caller had already one going.

Schema versioning:
It's unfortunate that we need to have explicit elements in the page for the 
versioning protocol to work, but the fact that we can have a reliable mechanism 
for pages to coordinate a version bump is really nice. For folks that don't 
know about this the first time they build it, an explicit error message on the 
schema change timeout can explain where to start. I do think that there may be 
a need for non-breaking changes to the schema to happen without a "version 
dance". For example, query processors regularly create temporary tables during 
sorts and such. Those shouldn't require any coordination (maybe we allow 
non-versioned additions, or we just introduce temporary, unnamed tables that 
evaporate on commit() or database close()...).

Thanks
-pablo




Re: [IndexedDB] Current editor's draft

2010-07-12 Thread Andrei Popescu
Nikunj,

On Fri, Jul 9, 2010 at 8:21 PM, Nikunj Mehta  wrote:
>
>
> From my examples, it was clear that we need different object stores to be 
> opened in different modes. Currently dynamic scope supports this use case, 
> i.e., allow mode specification on a per object-store basis. Therefore, unless 
> we decide to de-support this use case, we would need to add this ability to 
> static scope transactions if dynamic scope transactions go out of v1.
>

I would be very grateful if you could help me understand the statement
above. Looking at your examples, we have:


function processShipment(shipment, callback) {
// we need to validate the part exists in this city first and that the
supplier is known
var txn = db.transaction(); //synchronous because requesting locks as I go along
var parts = txn.objectStore("part", IDBObjectStore.READ_ONLY);
var partRequest = parts.get(shipment.part);
partRequest.onerror = shipmentProcessingError;
partRequest.onsuccess = function(event) {
 // the required part exists and we have now locked at least that key-value
 // so that it won't disappear when we add the shipment.
 var suppliers = txn.objectStore("supplier", IDBObjectStore.READ_ONLY);
 var supplierRequest = suppliers.get(shipment.supplier);
 supplierRequest.onerror = shipmentProcessingError;
 supplierRequest.onsuccess = function(event) {
   // the required supplier exists and we have now locked that key-value
   // so that it won't disappear when we add the shipment.
   var shipments = db.objectStore("shipment", IDBObjectStore.READ_WRITE);
   var shipmentRequest = shipments.add(shipment);
   supplierRequest.onerror = shipmentProcessingError;
   shipmentRequest.onsuccess = function(event) {
 var txnRequest = event.transaction.commit();
 // before the callback, commit the stored record
 var key = event.result;
 txnRequest.oncommit = function() {
   callback(key); // which is the key generated during storage
 }
 txnRequest.onerror = shipmentProcessingError;
   }
 }

If I understand things right, this example processes a new shipment:
it checks that the part and supplier exist and then adds the new
shipment to the appropriate object store. And you are claiming that if
we leave dynamic transactions out of v1, then we need to de-support
this use case. Is this correct?

Now, would the code below support the same use case?

function processShipment(shipment, callback) {
  // We open a READ_WRITE transaction since we need to update the
shipments object store.
  var txnRequest = db.openTtransaction("part", "supplier",
"shipments", IDBObjectStore.READ_TRANSACTION);

  txnRequest.onsuccess = function(event) {
var txn = event.transaction;
var parts = txn.objectStore("part");
var partRequest = parts.get(shipment.part);

partRequest.onsuccess = function(event) {
  // the required part exists
  var suppliers = txn.objectStore("supplier");
  var supplierRequest = suppliers.get(shipment.supplier);

  supplierRequest.onsuccess = function(event) {
// the required supplier exists
   var shipments = db.objectStore("shipment");
   var shipmentRequest = shipments.add(shipment);

   shipmentRequest.onsuccess = function(event) {
 var key = event.result;
 txnRequest.oncommit = function() {
   callback(key); // which is the key generated during storage
 }
   }
 }
   }
}

So if the above supports the same use case (albeit by allowing less
concurrency), then we dropping dynamic transactions doesn't mean we
lose this use case. Is this right? Are there any other use cases you
think we could lose? I could not find them in your examples.

Thanks,
Andrei



Re: [IndexedDB] Current editor's draft

2010-07-10 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 6:27 PM, Jonas Sicking  wrote:
>> I also did not hear from you about explicit commits. Did that mean that you 
>> agree with that part of my proposal? There are several examples where it 
>> makes sense to explicitly commit, although it is automatic in some cases.
>
> I haven't yet had time to analyze this. I wanted to do so before
> commenting. I don't have time right now, but will do so tomorrow.

Ok, I looked at the example functions that you supplied in the
original email in this thread.

As far as I can see, in every instance where you are calling
.commit(), if you simply removed the call to .commit() that would not
change the behavior of the code. Am I missing something?

The only exception is the following code in processShipment:

 var txnRequest = event.transaction.commit();
 // before the callback, commit the stored record
 var key = event.result;
 txnRequest.oncommit = function() {
   callback(key); // which is the key generated during storage
 }
 txnRequest.onerror = shipmentProcessingError;

where you are using the return value from .commit(). However I suspect
there is a bug in this code as .commit() in your proposal is defined
to return void. And even if it does return an IDBRequest, that object
does not have an oncommit property. I suspect you intended the code to
say:

 event.transaction.commit();
 // before the callback, commit the stored record
 var key = event.result;
 event.transaction.oncomplete = function() {
   callback(key); // which is the key generated during storage
 }
 event.transaction.onerror = shipmentProcessingError;

With this fix, here too the call to .commit() seems to be removeable
without affecting behavior.

Please let me know if I'm missing something?

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-10 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 12:50 PM, Nikunj Mehta  wrote:
>
> On Jul 10, 2010, at 12:29 AM, Jonas Sicking wrote:
>
>> On Fri, Jul 9, 2010 at 11:05 AM, Nikunj Mehta  wrote:
>>> We would not make dynamic transactions be the default since they would
>>> produce more concurrency than static scoped transactions, correct?
>>> On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:
>>
>> I'm not sure I understand the question. We would use separate
>> functions for creating dynamic and static transactions so there is no
>> such thing as "default".
>
> The point is that we are talking of leaving out dynamic scope in v1, while, 
> in the same vein, talking of making READ_ONLY the default _because_ it 
> produces "good" performance. That is, IMHO, contradictory.

I think you are using flawed logic. Just because I want to remove one
feature that can be used to increase performance doesn't mean that I
hate performance and want to design all other features to be as slow
as possible.

I'm not arguing for removing dynamic transactions because I don't care
about performance. I'm arguing for removing dynamic transactions
because I think it's too hard for authors to use them correctly.

I absolutely care about performance, that is why I think we should use
READ_ONLY as default.

>>> Unless we're planning on making all
>>> transactions dynamic (I hope not), locks have to be grabbed when the
>>> transaction is created, right? If a transaction is holding a READ_ONLY
>>>
>>> lock for a given objectStore, then attempting to open that objectStore
>>>
>>> as READ_WRITE should obviously fail. Consecutively, if a transaction
>>>
>>> is holding a READ_WRITE lock for a given objectStore, then opening
>>>
>>> that objectStore as READ_ONLY doesn't seem to have any benefit over
>>>
>>> opening it as READ_WRITE. In short, I can't see any situation when
>>>
>>> you'd want to open an objectStore in a different mode than what was
>>>
>>> used when the transaction was created.
>>>
>>> Finally, I would stronly prefer to have READ_ONLY be the default
>>>
>>> transaction type if none is specified by the author. It is better to
>>>
>>> default to what results in higher performance, and have people notice
>>>
>>> when they need to switch to the slower mode. This is because people
>>>
>>> will very quickly notice if they use READ_ONLY when they need to use
>>>
>>> READ_WRITE, since the code will never work. However if people use
>>>
>>> READ_WRITE when all they need is READ_ONLY, then the only effect is
>>>
>>> likely to be an application that runs somewhat slower, when they will
>>>
>>> unlikely detect.
>>>
>>> This approach is also likely to cause exceptions upon put, remove, and add.
>>>
>>> I would prefer to not cause exceptions as the default behavior.
>>>
>>> If we use READ_WRITE as default behavior then it's extremely likely
>>> that people will use the wrong lock type and not realize. The downside
>>> will be that sites will run less concurrently, and thus slower, than
>>> they could.
>>>
>>> All along our primary objective with IndexedDB is to assist programmers who
>>> are not well versed with database programming to be able to write simple
>>> programs without errors. By that token, reducing the effort required for
>>> their use of IndexedDB seems to be the primary criteria and not great
>>> concurrency.
>>
>> As far as I can see this does not significantly complicate
>> development.
>
> This seems to be conveniently justified. A strict interpretation of the 
> objective would not require the programmer to specify READ_WRITE even though 
> that involves less mental (cognitive) and physical (typing) effort.

I simply don't use as strict interpretation of the objective of
simplifying development. Not every single decision we make will come
down in favor of what makes a simpler API.  Every decision we make is
a judgement call as there are advantages and disadvantages with
everything. I enumerated those advantages and disadvantages above and
I think think the advantages of using READ_ONLY are stronger.

>> In fact, in the process of writing test cases I have
>> several times forgotten to specify lock type. For the cases when I
>> needed a READ_WRITE lock, the code didn't work.
>
> It should have worked right the first time. Why wait for a programmer to find 
> out why their code didn't work?

We can't ever prevent all mistakes. My point is that this mistake did
not meaningfully affect my ability to write working code.

I think we simply have to agree to disagree. Based on that, I'm
curious to know what other people think. So far it seems like mozilla
and google has come out in favor of using READ_ONLY as default.

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 12:21 PM, Nikunj Mehta  wrote:

>>>
>>> I don't think it's even possible with the current API since
>>> openTransaction() takes a list of objectStore names but a single mode.
>>
>> Indeed. We could allow static transactions to use different lock
>> levels for different objectStores, all specified when the
>> IDBTransaction is initially created. It's just a matter of syntax to
>> the IDBDatabase.transaction() function. However so far I've thought
>> that we should leave this for v2. But if people would feel more easy
>> about dropping dynamic transactions if we add this ability, then I
>> would be ok with it.
>
> From my examples, it was clear that we need different object stores to be 
> opened in different modes. Currently dynamic scope supports this use case, 
> i.e., allow mode specification on a per object-store basis. Therefore, unless 
> we decide to de-support this use case, we would need to add this ability to 
> static scope transactions if dynamic scope transactions go out of v1.

I don't see why you couldn't always open all needed objectStores in
READ_WRITE mode? Can you point to the specific function where this
wouldn't be possible?

 If it is the case that specifying a mode when opening an objectStore
 only makes sense on dynamic transactions, then I think we should only
 expose that argument on dynamic transactions.

 Now that I understand your proposal better, I don't understand how
 IDBTransaction.objectStore works for dynamically scoped transactions
 in your proposal. It seems to require synchronously grabbing a lock
 which I thought we wanted to avoid at all cost.
>
> See below.
>

>>>
>>> This is rather confusing: is IDBTransaction::objectStore() creating an
>>> object store, now? If yes, then it must lock it synchronously. If it just
>>> returns an object store that was previously added to the transaction, what
>>> is the 'mode' parameter for?
>>
>> Looking at Nikunj's example code, it seems like you can request a new
>> objectStore to be locked using IDBTransaction.objectStore(). Not sure
>> if that is a bug or not though?
>
> That was a bug. For dynamic transactions, obtaining an object store would 
> have to be asynchronous as it involves obtaining a lock.

Ok, so what happens if IDBTransaction.objectStore is called during a
dynamic transaction? Or if IDBDatabase.openObjectStore is called from
a static transaction? What if IDBDatabase.openObjectStore is called
from a static transaction using a objectStore name which wasn't locked
when the transaction was created?

I really think we need to separate the interfaces for dynamic and
static transactions and have the synchronous .objectStore only
available on static transactions, while the asynchronous
.openObjectStore needs to be available only on dynamic transactions.

> I also did not hear from you about explicit commits. Did that mean that you 
> agree with that part of my proposal? There are several examples where it 
> makes sense to explicitly commit, although it is automatic in some cases.

I haven't yet had time to analyze this. I wanted to do so before
commenting. I don't have time right now, but will do so tomorrow.

/ Jonas



Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 11:44 AM, Nikunj Mehta  wrote:
>
> On Jul 8, 2010, at 12:38 AM, Jonas Sicking wrote:
>
>> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>>>
>>>
>>> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:

 On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
> On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
>>
>> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
>> wrote:
>>> Hi folks,
>>>
>>> There are several unimplemented proposals on strengthening and
>>> expanding IndexedDB. The reason I have not implemented them yet is
>>> because I am not convinced they are necessary in toto. Here's my
>>> attempt at explaining why. I apologize in advance for not responding
>>> to individual proposals due to personal time constraints. I will
>>> however respond in detail on individual bug reports, e.g., as I did
>>> with 9975.
>>>
>>> I used the current editor's draft asynchronous API to understand
>>> where
>>> some of the remaining programming difficulties remain. Based on this
>>> attempt, I find several areas to strengthen, the most prominent of
>>> which is how we use transactions. Another is to add the concept of a
>>> catalog as a special kind of object store.
>>
>> Hi Nikunj,
>>
>> Thanks for replying! I'm very interested in getting this stuff sorted
>> out pretty quickly as almost all other proposals in one way or another
>> are affected by how this stuff develops.
>>
>>> Here are the main areas I propose to address in the editor's spec:
>>>
>>> 1. It is time to separate the dynamic and static scope transaction
>>> creation so that they are asynchronous and synchronous respectively.
>>
>> I don't really understand what this means. What are dynamic and static
>> scope transaction creation? Can you elaborate?
>
> This is the difference in the API in my email between openTransaction
> and
> transaction. Dynamic and static scope have been defined in the spec for
> a
> long time.

>>>
>>> In fact, dynamic transactions aren't explicitly specified anywhere. They are
>>> just mentioned. You need some amount of guessing to find out what they are
>>> or how to create one (i.e. pass an empty list of store names).
>>
>> Yes, that has been a big problem for us too.
>>
 Ah, I think I'm following you now. I'm actually not sure that we
 should have dynamic scope at all in the spec, I know Jeremy has
 expressed similar concerns. However if we are going to have dynamic
 scope, I agree it is a good idea to have separate APIs for starting
 dynamic-scope transactions from static-scope transactions.

>>>
>>> I think it would simplify matters a lot if we were to drop dynamic
>>> transactions altogether. And if we do that,  then we can also safely move
>>> the 'mode' to parameter to the Transaction interface, since all the object
>>> stores in a static transaction can be only be open in the same mode.
>>
>> Agreed.
>>
>>> 2. Provide a catalog object that can be used to atomically add/remove
>>> object stores and indexes as well as modify version.
>>
>> It seems to me that a catalog object doesn't really provide any
>> functionality over the proposal in bug 10052? The advantage that I see
>> with the syntax proposal in bug 10052 is that it is simpler.
>>
>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>>
>> Can you elaborate on what the advantages are of catalog objects?
>
> To begin with, 10052 shuts down the "users" of the database completely
> when
> only one is changing its structure, i.e., adding or removing an object
> store.

 This is not the case. Check the steps defined for setVersion in [1].
 At no point are databases shut down automatically. Only once all
 existing database connections are manually closed, either by calls to
 IDBDatabase.close() or by the user leaving the page, is the 'success'
 event from setVersion fired.

 [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0

> How can we make it less draconian?

 The 'versionchange' event allows pages that are currently using the
 database to handle the change. The page can inspect the new version
 number supplied by the 'versionchange' event, and if it knows that it
 is compatible with a given upgrade, all it needs to do is to call
 db.close() and then immediately reopen the database using
 indexedDB.open(). The open call won't complete until the upgrade is
 finished.

>>>
>>> I had a question here: why does the page need to call 'close'? Any pending
>>> transactions will run to completion and new ones should not be allowed to
>>> start if a VERSION_CHANGE transaction is waiting to start. From the
>>> description of what 'close' does in 10052, I am not entirely sure it is
>>> needed.
>>
>> The p

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 11:27 AM, Nikunj Mehta  wrote:
>
> On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:
>
> 2. Provide a catalog object that can be used to atomically add/remove
> object stores and indexes as well as modify version.

 It seems to me that a catalog object doesn't really provide any
 functionality over the proposal in bug 10052? The advantage that I see
 with the syntax proposal in bug 10052 is that it is simpler.

 http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052

 Can you elaborate on what the advantages are of catalog objects?
>>>
>>> To begin with, 10052 shuts down the "users" of the database completely when
>>> only one is changing its structure, i.e., adding or removing an object
>>> store.
>>
>> This is not the case. Check the steps defined for setVersion in [1].
>> At no point are databases shut down automatically. Only once all
>> existing database connections are manually closed, either by calls to
>> IDBDatabase.close() or by the user leaving the page, is the 'success'
>> event from setVersion fired.
>
> Can you justify why one should be forced to stop using the database when 
> someone else is adding an object store or an index? This is what I meant by 
> draconian.

In the thread "[IndexedDB] Atomic schema changes" the conclusion was
that while it's possible to create API that allows compatible schema
changes without calling setVersion, it wasn't worth the added API
complexity. It's something that can wait for v2. Are calls to add
indexes and objectStores without further incompatible changes common
enough that we need to optimize the case when users have multiple tabs
open? Remember that calling setVersion really is no overhead if only
one copy of the application is running.

>> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>>
>>> How can we make it less draconian?
>>
>> The 'versionchange' event allows pages that are currently using the
>> database to handle the change. The page can inspect the new version
>> number supplied by the 'versionchange' event, and if it knows that it
>> is compatible with a given upgrade, all it needs to do is to call
>> db.close() and then immediately reopen the database using
>> indexedDB.open(). The open call won't complete until the upgrade is
>> finished.
>>
>>> Secondly, I don't see how that
>>> approach can produce atomic changes to the database.
>>
>> When the transaction created in step 4 of setVersion defined in [1] is
>> created, only one IDBDatabase object to the database is open. As long
>> as that transaction is running, no requests returned from
>> IDBFactory.open will receive a 'success' event. Only once the
>> transaction is committed, or aborted, will those requests succeed.
>> This guarantees that no other IDBDatabase object can see a partial
>> update.
>>
>> Further, only once the transaction created by setVersion is committed,
>> are the requested objectStores and indexes created/removed. This
>> guarantees that the database is never left with a partial update.
>>
>> That means that the changes are atomic, right?
>
> Atomic is not the same is isolated. Merely the fact that no other use of the 
> database was being made when you are changing its structure doesn't mean that 
> you will get all of the changes or none. What happens, for example, if the 
> browser crashes in the middle of the versionRequest.onsuccess handler?

Yeah, I forgot one critical piece of information. Like with any other
transaction. If the transaction isn't successfully committed, it is
fully rolled back and no changes whatsoever are made to the database.

>>> Thirdly, we shouldn't
>>> need to change version in order to perform database changes.
>>
>> First off, note that if the upgrade is compatible, you can just pass
>> the existing database version to setVersion. So no version *change* is
>> actually needed.
>>
>> Second, I don't think there is much difference between
>>
>> var txn = db.transaction();
>> db.openCatalog(txn).onsuccess = ...
>>
>> vs
>>
>> db.setVersion("5").onsuccess = ...
>>
>> I don't see that telling people that they have to use the former is a big 
>> win.
>>
>>
>> The problem that I see with the catalog proposal, if I understand it
>> correctly, is that it means that a page that has a IDBDatabase object
>> open has to always be prepared for calls to
>> openObjectStore/openTransaction failing. I.e. the page can't ever know
>> that another page was opened which at any point created a catalog and
>> removed an objectStore. This forces pages to at every single call
>> either check that the version is still the same, or that each and
>> every call to openObjectStore/openTransaction succeeds. This seems
>> very error prone to me.
>
> We could easily add a condition check to removing an object store so that 
> there are no open transactions holding a lock on that object store. This 
> would prevent any errors of the kind you describe.

I don't see that that would help. You're still i

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Shawn Wilsher

 On 7/9/2010 12:50 PM, Nikunj Mehta wrote:

The point is that we are talking of leaving out dynamic scope in v1, while, in the same 
vein, talking of making READ_ONLY the default _because_ it produces "good" 
performance. That is, IMHO, contradictory.
Dynamic scope == dynamic transactions, correct?  Can you please 
elaborate on how dynamic transactions improve performance?



This seems to be conveniently justified. A strict interpretation of the 
objective would not require the programmer to specify READ_WRITE even though 
that involves less mental (cognitive) and physical (typing) effort.
FWIW, this isn't constructive.  Your argument also seems to assume that 
writes are more common than reads, which hasn't been my experience with 
this API.



It should have worked right the first time. Why wait for a programmer to find 
out why their code didn't work?
Why make writing code with good performance characteristics the uncommon 
case?  We clearly have two different schools of thoughts here, and I'm 
not sure we are going to find a consensus...



There are many ways to get performance improvement, including dynamic 
transactions, which you seem not to be favorable towards. I don't see why 
READ_ONLY should be given special treatment.
It's unclear to me why you think READ_ONLY is getting special treatment 
(or what that even means in this context).



Various hints are used in SQL syntax, e.g., [1], to manage locks, a certain 
kind of B-tree behavior, or a level of isolation. These are all aimed at 
improving performance, but they are set as default behavior. My point is that 
expecting good performance from a single variable in database systems out of 
possibly hundreds is not all that helpful. It is also a slippery slope because 
it confuses performance with options. The database's job is to be fast at what 
it does, not play performance tricks using default values.
While I think this argument makes sense in some cases, I really don't 
feel like it applies at all in this situation.  Even the page you linked 
to says "Because the SQL Server query optimizer typically selects the 
best execution plan for a query..." which in most cases would be 
READ_ONLY (based on evidence the Mozilla team has from demos written).  
The default should represent the commonly used case.


I don't know that we can make the right performance decisions for 
people. What we can do is make things perform well and provide tools 
to improve performance.
We aren't making performance decisions though; we are just picking the 
default to be the most commonly used option.  It just happens to be the 
one to allow more concurrency.


Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Shawn Wilsher

 On 7/9/2010 11:05 AM, Nikunj Mehta wrote:

We would not make dynamic transactions be the default since they would produce 
more concurrency than static scoped transactions, correct?
I'm still of the opinion that dynamic transactions are a bad idea 
because it's too easy to hold a transaction open for a long period of 
time, making it easy for programmers to write incorrect/buggy code.


All along our primary objective with IndexedDB is to assist 
programmers who are not well versed with database programming to be 
able to write simple programs without errors. By that token, reducing 
the effort required for their use of IndexedDB seems to be the primary 
criteria and not great concurrency.
Er, I thought we were targeting libraries but still wanted this to be 
simple to use.  Regardless, allowing for more concurrency doesn't hurt 
ease of use in any of what we've discussed so far (as far as I can tell).



Another downside is that authors should specify lock-type
more often, for optimal performance, if we think that READ_ONLY is
more common.

You haven't provided any evidence about this yet.
I can assert that all the demos I've written (admittedly not many), 
simply reading from the database has been far more common than writing 
to it.  It's pretty much "write data in" but then do all operations on 
the local database.


It is quite common in various languages to specify as a performance or 
safety hint when someone desires a shared lock and use a read-write 
version by default.
You seem to have contradictory statements here.  Earlier you argued that 
"reducing the effort required for their [programmers] use of IndexedDB 
seems to be the primary criteria", but having them to read and know 
performance or safety hints seems to me like we are making the API more 
complicated.  Having simple clear API calls with sensible error messages 
on misuse is far better than having an API that you can use one way (the 
most common way) but would be more efficient if you use it another way.



For all we know, programmers would lock the entire database when they create a 
transaction. If dynamic transactions appear to be a non-v1 feature, then 
READ_ONLY being default appears out of place.
You asked Jonas for data backing up his claims, and now I'm going to ask 
the same of you.  It's been my experience and Ben Turner's experience 
that defaulting to READ_ONLY results in less code being written using 
this API.  Reads are far more common than writes (in databases in 
general, I think although edge cases certainly exist), so it makes sense 
to make that the default.


Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Andrei Popescu
Hi Nikunj,

On Fri, Jul 9, 2010 at 7:31 PM, Nikunj Mehta  wrote:
> Andrei,
>
> Pejorative remarks about normative text don't help anyone. If you think that 
> the spec text is not clear or that you are unable to interpret it, please say 
> so. The text about dynamic scope has been around for long enough and no one 
> so far mentioned a problem with them.
>

I didn't mean anything disrespectful, I'm sorry if it sounded that
way. I was just stating that, as far as I can tell, the spec is not
clear about dynamic transactions.

Thanks,
Andrei



Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta

On Jul 10, 2010, at 12:29 AM, Jonas Sicking wrote:

> On Fri, Jul 9, 2010 at 11:05 AM, Nikunj Mehta  wrote:
>> We would not make dynamic transactions be the default since they would
>> produce more concurrency than static scoped transactions, correct?
>> On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:
> 
> I'm not sure I understand the question. We would use separate
> functions for creating dynamic and static transactions so there is no
> such thing as "default".

The point is that we are talking of leaving out dynamic scope in v1, while, in 
the same vein, talking of making READ_ONLY the default _because_ it produces 
"good" performance. That is, IMHO, contradictory.

> 
>> Unless we're planning on making all
>> transactions dynamic (I hope not), locks have to be grabbed when the
>> transaction is created, right? If a transaction is holding a READ_ONLY
>> 
>> lock for a given objectStore, then attempting to open that objectStore
>> 
>> as READ_WRITE should obviously fail. Consecutively, if a transaction
>> 
>> is holding a READ_WRITE lock for a given objectStore, then opening
>> 
>> that objectStore as READ_ONLY doesn't seem to have any benefit over
>> 
>> opening it as READ_WRITE. In short, I can't see any situation when
>> 
>> you'd want to open an objectStore in a different mode than what was
>> 
>> used when the transaction was created.
>> 
>> Finally, I would stronly prefer to have READ_ONLY be the default
>> 
>> transaction type if none is specified by the author. It is better to
>> 
>> default to what results in higher performance, and have people notice
>> 
>> when they need to switch to the slower mode. This is because people
>> 
>> will very quickly notice if they use READ_ONLY when they need to use
>> 
>> READ_WRITE, since the code will never work. However if people use
>> 
>> READ_WRITE when all they need is READ_ONLY, then the only effect is
>> 
>> likely to be an application that runs somewhat slower, when they will
>> 
>> unlikely detect.
>> 
>> This approach is also likely to cause exceptions upon put, remove, and add.
>> 
>> I would prefer to not cause exceptions as the default behavior.
>> 
>> If we use READ_WRITE as default behavior then it's extremely likely
>> that people will use the wrong lock type and not realize. The downside
>> will be that sites will run less concurrently, and thus slower, than
>> they could.
>> 
>> All along our primary objective with IndexedDB is to assist programmers who
>> are not well versed with database programming to be able to write simple
>> programs without errors. By that token, reducing the effort required for
>> their use of IndexedDB seems to be the primary criteria and not great
>> concurrency.
> 
> As far as I can see this does not significantly complicate
> development.

This seems to be conveniently justified. A strict interpretation of the 
objective would not require the programmer to specify READ_WRITE even though 
that involves less mental (cognitive) and physical (typing) effort. 

> In fact, in the process of writing test cases I have
> several times forgotten to specify lock type. For the cases when I
> needed a READ_WRITE lock, the code didn't work.

It should have worked right the first time. Why wait for a programmer to find 
out why their code didn't work? 

> As always when things
> don't work my first reaction was to go look at the error console which
> showed a uncaught exception which immediately showed what the problem
> was.

> 
> So I argue that this does not meaningfully increase the effort
> required to use IndexedDB.
> 
> Using the other lock type as default does however meaningfully
> increase the effort required to get optimal performance, which I think
> we should take into account.

There are many ways to get performance improvement, including dynamic 
transactions, which you seem not to be favorable towards. I don't see why 
READ_ONLY should be given special treatment.

> 
>> Another downside is that authors should specify lock-type
>> more often, for optimal performance, if we think that READ_ONLY is
>> more common.
>> 
>> You haven't provided any evidence about this yet.
> 
> Certainly. I was just enumerating all the reasons I could think of why
> either default would be preferable. I similarly haven't seen any
> evidence why write transactions are more common.
> 
> Though I will note that both the example programs that you have
> written, as well as ones we have written for a few demos, use more
> read transactions than write transactions. (I can attach those if
> anyone is interested, though note that they are very specific to the
> API we currently have implemented).
> 
>> If we are using READ_ONLY as default behavior, then it's extremely
>> likely that people will use the wrong lock type, notice that their
>> code isn't working, and fix it. The downside is that people will have
>> to fix their bugs. Another downside is that authors will have to
>> specify lock-type more often if we think that READ_WRITE is m

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta

On Jul 8, 2010, at 12:38 AM, Jonas Sicking wrote:

> 
> One of our main points was to make getting objectStore
> objects a synchronous operation as to avoid having to nest multiple
> levels of asynchronous calls. Compare
> 
> var req = db.openObjectStore("foo", trans);
> req.onerror = errorHandler;
> req.onsuccess = function(e) {
>  var fooStore = e.result;
>  var req = fooStore.get(12);
>  req.onerror = errorHandler;
>  req.onsuccess = resultHandler;
> }
> 
> to
> 
> var fooStore = db.openObjectStore("foo", trans);
> var req = fooStore.get(12);
> req.onerror = errorHandler;
> req.onsuccess = resultHandler;
> 
> 
> I also don't understand the advantage of having the transaction as an
> argument to openObjectStore rather than having openObjectStore live on
> transaction. Compare
> 
> db.openObjectStore("foo", trans);
> 
> to
> 
> trans.openObjectStore("foo");
> 
> I also don't understand the meaning of specifying a mode when a
> objectStore is opened, rather than specifying the mode when the
> transaction is created.
 
 Have you reviewed the examples? Different object stores in a transaction
 are
 used in different modes, and that requires us to identify the mode when
 opening the object store. This also increases concurrency. This is
 particularly useful for dynamic transactions.
>>> 
>>> I'm following you better now. I do see how this can work for dynamic
>>> transactions where locks are not acquired upon creation of the
>>> transaction. But I don't see how this makes sense for static
>>> transactions. And it indeed seems like you are not using this feature
>>> for static transactions.

The feature is targeted for use in dynamic scope.

>>> 
>> 
>> I don't think it's even possible with the current API since
>> openTransaction() takes a list of objectStore names but a single mode.
> 
> Indeed. We could allow static transactions to use different lock
> levels for different objectStores, all specified when the
> IDBTransaction is initially created. It's just a matter of syntax to
> the IDBDatabase.transaction() function. However so far I've thought
> that we should leave this for v2. But if people would feel more easy
> about dropping dynamic transactions if we add this ability, then I
> would be ok with it.

From my examples, it was clear that we need different object stores to be 
opened in different modes. Currently dynamic scope supports this use case, 
i.e., allow mode specification on a per object-store basis. Therefore, unless 
we decide to de-support this use case, we would need to add this ability to 
static scope transactions if dynamic scope transactions go out of v1.

> 
>>> If it is the case that specifying a mode when opening an objectStore
>>> only makes sense on dynamic transactions, then I think we should only
>>> expose that argument on dynamic transactions.
>>> 
>>> Now that I understand your proposal better, I don't understand how
>>> IDBTransaction.objectStore works for dynamically scoped transactions
>>> in your proposal. It seems to require synchronously grabbing a lock
>>> which I thought we wanted to avoid at all cost.

See below.

>>> 
>> 
>> This is rather confusing: is IDBTransaction::objectStore() creating an
>> object store, now? If yes, then it must lock it synchronously. If it just
>> returns an object store that was previously added to the transaction, what
>> is the 'mode' parameter for?
> 
> Looking at Nikunj's example code, it seems like you can request a new
> objectStore to be locked using IDBTransaction.objectStore(). Not sure
> if that is a bug or not though?

That was a bug. For dynamic transactions, obtaining an object store would have 
to be asynchronous as it involves obtaining a lock.

I also did not hear from you about explicit commits. Did that mean that you 
agree with that part of my proposal? There are several examples where it makes 
sense to explicitly commit, although it is automatic in some cases.





Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta

On Jul 8, 2010, at 4:17 AM, Shawn Wilsher wrote:

> On 7/6/2010 6:31 PM, Nikunj Mehta wrote:
>> To begin with, 10052 shuts down the "users" of the database completely when
>> only one is changing its structure, i.e., adding or removing an object
>> store. How can we make it less draconian? Secondly, I don't see how that
>> approach can produce atomic changes to the database. Thirdly, we shouldn't
>> need to change version in order to perform database changes. Finally, I am
>> not sure why you consider the syntax proposal simpler. Note that I am not
>> averse to the version change event notification.
> In what use case would you want to change the database structure without 
> modifying the version?  That almost seems like a footgun for consumers.
> 

Can you justify your conclusion? 


Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta

On Jul 8, 2010, at 12:38 AM, Jonas Sicking wrote:

> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>> 
>> 
>> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:
>>> 
>>> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
 On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
> 
> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
> wrote:
>> Hi folks,
>> 
>> There are several unimplemented proposals on strengthening and
>> expanding IndexedDB. The reason I have not implemented them yet is
>> because I am not convinced they are necessary in toto. Here's my
>> attempt at explaining why. I apologize in advance for not responding
>> to individual proposals due to personal time constraints. I will
>> however respond in detail on individual bug reports, e.g., as I did
>> with 9975.
>> 
>> I used the current editor's draft asynchronous API to understand
>> where
>> some of the remaining programming difficulties remain. Based on this
>> attempt, I find several areas to strengthen, the most prominent of
>> which is how we use transactions. Another is to add the concept of a
>> catalog as a special kind of object store.
> 
> Hi Nikunj,
> 
> Thanks for replying! I'm very interested in getting this stuff sorted
> out pretty quickly as almost all other proposals in one way or another
> are affected by how this stuff develops.
> 
>> Here are the main areas I propose to address in the editor's spec:
>> 
>> 1. It is time to separate the dynamic and static scope transaction
>> creation so that they are asynchronous and synchronous respectively.
> 
> I don't really understand what this means. What are dynamic and static
> scope transaction creation? Can you elaborate?
 
 This is the difference in the API in my email between openTransaction
 and
 transaction. Dynamic and static scope have been defined in the spec for
 a
 long time.
>>> 
>> 
>> In fact, dynamic transactions aren't explicitly specified anywhere. They are
>> just mentioned. You need some amount of guessing to find out what they are
>> or how to create one (i.e. pass an empty list of store names).
> 
> Yes, that has been a big problem for us too.
> 
>>> Ah, I think I'm following you now. I'm actually not sure that we
>>> should have dynamic scope at all in the spec, I know Jeremy has
>>> expressed similar concerns. However if we are going to have dynamic
>>> scope, I agree it is a good idea to have separate APIs for starting
>>> dynamic-scope transactions from static-scope transactions.
>>> 
>> 
>> I think it would simplify matters a lot if we were to drop dynamic
>> transactions altogether. And if we do that,  then we can also safely move
>> the 'mode' to parameter to the Transaction interface, since all the object
>> stores in a static transaction can be only be open in the same mode.
> 
> Agreed.
> 
>> 2. Provide a catalog object that can be used to atomically add/remove
>> object stores and indexes as well as modify version.
> 
> It seems to me that a catalog object doesn't really provide any
> functionality over the proposal in bug 10052? The advantage that I see
> with the syntax proposal in bug 10052 is that it is simpler.
> 
> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
> 
> Can you elaborate on what the advantages are of catalog objects?
 
 To begin with, 10052 shuts down the "users" of the database completely
 when
 only one is changing its structure, i.e., adding or removing an object
 store.
>>> 
>>> This is not the case. Check the steps defined for setVersion in [1].
>>> At no point are databases shut down automatically. Only once all
>>> existing database connections are manually closed, either by calls to
>>> IDBDatabase.close() or by the user leaving the page, is the 'success'
>>> event from setVersion fired.
>>> 
>>> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>>> 
 How can we make it less draconian?
>>> 
>>> The 'versionchange' event allows pages that are currently using the
>>> database to handle the change. The page can inspect the new version
>>> number supplied by the 'versionchange' event, and if it knows that it
>>> is compatible with a given upgrade, all it needs to do is to call
>>> db.close() and then immediately reopen the database using
>>> indexedDB.open(). The open call won't complete until the upgrade is
>>> finished.
>>> 
>> 
>> I had a question here: why does the page need to call 'close'? Any pending
>> transactions will run to completion and new ones should not be allowed to
>> start if a VERSION_CHANGE transaction is waiting to start. From the
>> description of what 'close' does in 10052, I am not entirely sure it is
>> needed.
> 
> The problem we're trying to solve is this:
> 
> Imagine an editor which stores documents in indexedDB. However in
> order to not overwrite the

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 11:05 AM, Nikunj Mehta  wrote:
> We would not make dynamic transactions be the default since they would
> produce more concurrency than static scoped transactions, correct?
> On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:

I'm not sure I understand the question. We would use separate
functions for creating dynamic and static transactions so there is no
such thing as "default".

> Unless we're planning on making all
> transactions dynamic (I hope not), locks have to be grabbed when the
> transaction is created, right? If a transaction is holding a READ_ONLY
>
> lock for a given objectStore, then attempting to open that objectStore
>
> as READ_WRITE should obviously fail. Consecutively, if a transaction
>
> is holding a READ_WRITE lock for a given objectStore, then opening
>
> that objectStore as READ_ONLY doesn't seem to have any benefit over
>
> opening it as READ_WRITE. In short, I can't see any situation when
>
> you'd want to open an objectStore in a different mode than what was
>
> used when the transaction was created.
>
> Finally, I would stronly prefer to have READ_ONLY be the default
>
> transaction type if none is specified by the author. It is better to
>
> default to what results in higher performance, and have people notice
>
> when they need to switch to the slower mode. This is because people
>
> will very quickly notice if they use READ_ONLY when they need to use
>
> READ_WRITE, since the code will never work. However if people use
>
> READ_WRITE when all they need is READ_ONLY, then the only effect is
>
> likely to be an application that runs somewhat slower, when they will
>
> unlikely detect.
>
> This approach is also likely to cause exceptions upon put, remove, and add.
>
> I would prefer to not cause exceptions as the default behavior.
>
> If we use READ_WRITE as default behavior then it's extremely likely
> that people will use the wrong lock type and not realize. The downside
> will be that sites will run less concurrently, and thus slower, than
> they could.
>
> All along our primary objective with IndexedDB is to assist programmers who
> are not well versed with database programming to be able to write simple
> programs without errors. By that token, reducing the effort required for
> their use of IndexedDB seems to be the primary criteria and not great
> concurrency.

As far as I can see this does not significantly complicate
development. In fact, in the process of writing test cases I have
several times forgotten to specify lock type. For the cases when I
needed a READ_WRITE lock, the code didn't work. As always when things
don't work my first reaction was to go look at the error console which
showed a uncaught exception which immediately showed what the problem
was.

So I argue that this does not meaningfully increase the effort
required to use IndexedDB.

Using the other lock type as default does however meaningfully
increase the effort required to get optimal performance, which I think
we should take into account.

> Another downside is that authors should specify lock-type
> more often, for optimal performance, if we think that READ_ONLY is
> more common.
>
> You haven't provided any evidence about this yet.

Certainly. I was just enumerating all the reasons I could think of why
either default would be preferable. I similarly haven't seen any
evidence why write transactions are more common.

Though I will note that both the example programs that you have
written, as well as ones we have written for a few demos, use more
read transactions than write transactions. (I can attach those if
anyone is interested, though note that they are very specific to the
API we currently have implemented).

> If we are using READ_ONLY as default behavior, then it's extremely
> likely that people will use the wrong lock type, notice that their
> code isn't working, and fix it. The downside is that people will have
> to fix their bugs. Another downside is that authors will have to
> specify lock-type more often if we think that READ_WRITE is more
> common.
>
> It is quite common in various languages to specify as a performance or
> safety hint when someone desires a shared lock and use a read-write version
> by default.

I don't understand what you mean here. Could you elaborate?

> To me the downsides of using READ_WRITE as a default are much worse
> than the downsides of using READ_ONLY.
>
> For all we know, programmers would lock the entire database when they create
> a transaction. If dynamic transactions appear to be a non-v1 feature, then
> READ_ONLY being default appears out of place.

I don't understand why the lack of dynamic transactions would affect
what default lock type we should use for static transactions.

In fact, if you are concerned that lack of dynamic transactions will
cause people to lock the entire database and thus reduce concurrency
(is that your concern?), then it seems like using READ_ONLY as default
addresses that concern better than using READ

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta
Andrei,

Pejorative remarks about normative text don't help anyone. If you think that 
the spec text is not clear or that you are unable to interpret it, please say 
so. The text about dynamic scope has been around for long enough and no one so 
far mentioned a problem with them.

Nikunj
On Jul 7, 2010, at 11:11 PM, Andrei Popescu wrote:

> In fact, dynamic transactions aren't explicitly specified anywhere. They are 
> just mentioned. You need some amount of guessing to find out what they are or 
> how to create one (i.e. pass an empty list of store names).
> 




Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta

On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:

 2. Provide a catalog object that can be used to atomically add/remove
 object stores and indexes as well as modify version.
>>> 
>>> It seems to me that a catalog object doesn't really provide any
>>> functionality over the proposal in bug 10052? The advantage that I see
>>> with the syntax proposal in bug 10052 is that it is simpler.
>>> 
>>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>>> 
>>> Can you elaborate on what the advantages are of catalog objects?
>> 
>> To begin with, 10052 shuts down the "users" of the database completely when
>> only one is changing its structure, i.e., adding or removing an object
>> store.
> 
> This is not the case. Check the steps defined for setVersion in [1].
> At no point are databases shut down automatically. Only once all
> existing database connections are manually closed, either by calls to
> IDBDatabase.close() or by the user leaving the page, is the 'success'
> event from setVersion fired.

Can you justify why one should be forced to stop using the database when 
someone else is adding an object store or an index? This is what I meant by 
draconian.

> 
> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
> 
>> How can we make it less draconian?
> 
> The 'versionchange' event allows pages that are currently using the
> database to handle the change. The page can inspect the new version
> number supplied by the 'versionchange' event, and if it knows that it
> is compatible with a given upgrade, all it needs to do is to call
> db.close() and then immediately reopen the database using
> indexedDB.open(). The open call won't complete until the upgrade is
> finished.
> 
>> Secondly, I don't see how that
>> approach can produce atomic changes to the database.
> 
> When the transaction created in step 4 of setVersion defined in [1] is
> created, only one IDBDatabase object to the database is open. As long
> as that transaction is running, no requests returned from
> IDBFactory.open will receive a 'success' event. Only once the
> transaction is committed, or aborted, will those requests succeed.
> This guarantees that no other IDBDatabase object can see a partial
> update.
> 
> Further, only once the transaction created by setVersion is committed,
> are the requested objectStores and indexes created/removed. This
> guarantees that the database is never left with a partial update.
> 
> That means that the changes are atomic, right?

Atomic is not the same is isolated. Merely the fact that no other use of the 
database was being made when you are changing its structure doesn't mean that 
you will get all of the changes or none. What happens, for example, if the 
browser crashes in the middle of the versionRequest.onsuccess handler?


>> Thirdly, we shouldn't
>> need to change version in order to perform database changes.
> 
> First off, note that if the upgrade is compatible, you can just pass
> the existing database version to setVersion. So no version *change* is
> actually needed.
> 
> Second, I don't think there is much difference between
> 
> var txn = db.transaction();
> db.openCatalog(txn).onsuccess = ...
> 
> vs
> 
> db.setVersion("5").onsuccess = ...
> 
> I don't see that telling people that they have to use the former is a big win.
> 
> 
> The problem that I see with the catalog proposal, if I understand it
> correctly, is that it means that a page that has a IDBDatabase object
> open has to always be prepared for calls to
> openObjectStore/openTransaction failing. I.e. the page can't ever know
> that another page was opened which at any point created a catalog and
> removed an objectStore. This forces pages to at every single call
> either check that the version is still the same, or that each and
> every call to openObjectStore/openTransaction succeeds. This seems
> very error prone to me.

We could easily add a condition check to removing an object store so that there 
are no open transactions holding a lock on that object store. This would 
prevent any errors of the kind you describe. 

> 
> Looking at your example, it also seems like it contains a race
> condition. There is a risk that when someone opens a database, the
> first transaction, which uses a catalog to create the necessary
> objectStores and indexes, is committed, but the second transaction,
> which populates the objectStores with data, has not yet started.

I purposely wrote my example to allow database to be populated separately from 
the creation of the database. There is no reason why the two couldn't be done 
in the same transaction, though.

> 
>> Finally, I am
>> not sure why you consider the syntax proposal simpler. Note that I am not
>> averse to the version change event notification.
> 
> Compare to how your code would look like with the proposals in bugs
> 9975 and 10052:
> 
> var db;
> var dbRequest = indexedDB.open("parts", 'Part database');
> dbRequest.onsuccess = function(event) {
> db = event.result;
> if

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Nikunj Mehta
We would not make dynamic transactions be the default since they would produce 
more concurrency than static scoped transactions, correct?

On Jul 7, 2010, at 12:57 PM, Jonas Sicking wrote:

>>> Unless we're planning on making all
>>> transactions dynamic (I hope not), locks have to be grabbed when the
>>> transaction is created, right? If a transaction is holding a READ_ONLY
>>> lock for a given objectStore, then attempting to open that objectStore
>>> as READ_WRITE should obviously fail. Consecutively, if a transaction
>>> is holding a READ_WRITE lock for a given objectStore, then opening
>>> that objectStore as READ_ONLY doesn't seem to have any benefit over
>>> opening it as READ_WRITE. In short, I can't see any situation when
>>> you'd want to open an objectStore in a different mode than what was
>>> used when the transaction was created.
>>> 
>>> Finally, I would stronly prefer to have READ_ONLY be the default
>>> transaction type if none is specified by the author. It is better to
>>> default to what results in higher performance, and have people notice
>>> when they need to switch to the slower mode. This is because people
>>> will very quickly notice if they use READ_ONLY when they need to use
>>> READ_WRITE, since the code will never work. However if people use
>>> READ_WRITE when all they need is READ_ONLY, then the only effect is
>>> likely to be an application that runs somewhat slower, when they will
>>> unlikely detect.
>> 
>> This approach is also likely to cause exceptions upon put, remove, and add.
>> I would prefer to not cause exceptions as the default behavior.
> 
> If we use READ_WRITE as default behavior then it's extremely likely
> that people will use the wrong lock type and not realize. The downside
> will be that sites will run less concurrently, and thus slower, than
> they could.

All along our primary objective with IndexedDB is to assist programmers who are 
not well versed with database programming to be able to write simple programs 
without errors. By that token, reducing the effort required for their use of 
IndexedDB seems to be the primary criteria and not great concurrency. 

> Another downside is that authors should specify lock-type
> more often, for optimal performance, if we think that READ_ONLY is
> more common.

You haven't provided any evidence about this yet. 

> 
> If we are using READ_ONLY as default behavior, then it's extremely
> likely that people will use the wrong lock type, notice that their
> code isn't working, and fix it. The downside is that people will have
> to fix their bugs. Another downside is that authors will have to
> specify lock-type more often if we think that READ_WRITE is more
> common.

It is quite common in various languages to specify as a performance or safety 
hint when someone desires a shared lock and use a read-write version by 
default. 

> 
> To me the downsides of using READ_WRITE as a default are much worse
> than the downsides of using READ_ONLY.

For all we know, programmers would lock the entire database when they create a 
transaction. If dynamic transactions appear to be a non-v1 feature, then 
READ_ONLY being default appears out of place.

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Jonas Sicking
On Fri, Jul 9, 2010 at 3:21 AM, Andrei Popescu  wrote:
> On Thu, Jul 8, 2010 at 8:27 PM, Jonas Sicking  wrote:
>> On Thu, Jul 8, 2010 at 8:22 AM, Andrei Popescu  wrote:
>>> Hi Jonas,
>>>
>>> On Wed, Jul 7, 2010 at 8:08 PM, Jonas Sicking  wrote:
 On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>
>
> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:
>>
>> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
>> > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
>> >>
>> >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
>> >> wrote:
>> >> > Hi folks,
>> >> >
>> >> > There are several unimplemented proposals on strengthening and
>> >> > expanding IndexedDB. The reason I have not implemented them yet is
>> >> > because I am not convinced they are necessary in toto. Here's my
>> >> > attempt at explaining why. I apologize in advance for not responding
>> >> > to individual proposals due to personal time constraints. I will
>> >> > however respond in detail on individual bug reports, e.g., as I did
>> >> > with 9975.
>> >> >
>> >> > I used the current editor's draft asynchronous API to understand
>> >> > where
>> >> > some of the remaining programming difficulties remain. Based on this
>> >> > attempt, I find several areas to strengthen, the most prominent of
>> >> > which is how we use transactions. Another is to add the concept of a
>> >> > catalog as a special kind of object store.
>> >>
>> >> Hi Nikunj,
>> >>
>> >> Thanks for replying! I'm very interested in getting this stuff sorted
>> >> out pretty quickly as almost all other proposals in one way or another
>> >> are affected by how this stuff develops.
>> >>
>> >> > Here are the main areas I propose to address in the editor's spec:
>> >> >
>> >> > 1. It is time to separate the dynamic and static scope transaction
>> >> > creation so that they are asynchronous and synchronous respectively.
>> >>
>> >> I don't really understand what this means. What are dynamic and static
>> >> scope transaction creation? Can you elaborate?
>> >
>> > This is the difference in the API in my email between openTransaction
>> > and
>> > transaction. Dynamic and static scope have been defined in the spec for
>> > a
>> > long time.
>>
>
> In fact, dynamic transactions aren't explicitly specified anywhere. They 
> are
> just mentioned. You need some amount of guessing to find out what they are
> or how to create one (i.e. pass an empty list of store names).

 Yes, that has been a big problem for us too.

>> Ah, I think I'm following you now. I'm actually not sure that we
>> should have dynamic scope at all in the spec, I know Jeremy has
>> expressed similar concerns. However if we are going to have dynamic
>> scope, I agree it is a good idea to have separate APIs for starting
>> dynamic-scope transactions from static-scope transactions.
>>
>
> I think it would simplify matters a lot if we were to drop dynamic
> transactions altogether. And if we do that,  then we can also safely move
> the 'mode' to parameter to the Transaction interface, since all the object
> stores in a static transaction can be only be open in the same mode.

 Agreed.

>> >> > 2. Provide a catalog object that can be used to atomically 
>> >> > add/remove
>> >> > object stores and indexes as well as modify version.
>> >>
>> >> It seems to me that a catalog object doesn't really provide any
>> >> functionality over the proposal in bug 10052? The advantage that I see
>> >> with the syntax proposal in bug 10052 is that it is simpler.
>> >>
>> >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>> >>
>> >> Can you elaborate on what the advantages are of catalog objects?
>> >
>> > To begin with, 10052 shuts down the "users" of the database completely
>> > when
>> > only one is changing its structure, i.e., adding or removing an object
>> > store.
>>
>> This is not the case. Check the steps defined for setVersion in [1].
>> At no point are databases shut down automatically. Only once all
>> existing database connections are manually closed, either by calls to
>> IDBDatabase.close() or by the user leaving the page, is the 'success'
>> event from setVersion fired.
>>
>> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>>
>> > How can we make it less draconian?
>>
>> The 'versionchange' event allows pages that are currently using the
>> database to handle the change. The page can inspect the new version
>> number supplied by the 'versionchange' event, and if it knows that it
>> is compatible with a given upgrade, all it needs to do is to call
>> db.close() and then immediately reopen the database 

Re: [IndexedDB] Current editor's draft

2010-07-09 Thread Andrei Popescu
On Thu, Jul 8, 2010 at 8:27 PM, Jonas Sicking  wrote:
> On Thu, Jul 8, 2010 at 8:22 AM, Andrei Popescu  wrote:
>> Hi Jonas,
>>
>> On Wed, Jul 7, 2010 at 8:08 PM, Jonas Sicking  wrote:
>>> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:


 On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:
>
> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
> > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
> >>
> >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
> >> wrote:
> >> > Hi folks,
> >> >
> >> > There are several unimplemented proposals on strengthening and
> >> > expanding IndexedDB. The reason I have not implemented them yet is
> >> > because I am not convinced they are necessary in toto. Here's my
> >> > attempt at explaining why. I apologize in advance for not responding
> >> > to individual proposals due to personal time constraints. I will
> >> > however respond in detail on individual bug reports, e.g., as I did
> >> > with 9975.
> >> >
> >> > I used the current editor's draft asynchronous API to understand
> >> > where
> >> > some of the remaining programming difficulties remain. Based on this
> >> > attempt, I find several areas to strengthen, the most prominent of
> >> > which is how we use transactions. Another is to add the concept of a
> >> > catalog as a special kind of object store.
> >>
> >> Hi Nikunj,
> >>
> >> Thanks for replying! I'm very interested in getting this stuff sorted
> >> out pretty quickly as almost all other proposals in one way or another
> >> are affected by how this stuff develops.
> >>
> >> > Here are the main areas I propose to address in the editor's spec:
> >> >
> >> > 1. It is time to separate the dynamic and static scope transaction
> >> > creation so that they are asynchronous and synchronous respectively.
> >>
> >> I don't really understand what this means. What are dynamic and static
> >> scope transaction creation? Can you elaborate?
> >
> > This is the difference in the API in my email between openTransaction
> > and
> > transaction. Dynamic and static scope have been defined in the spec for
> > a
> > long time.
>

 In fact, dynamic transactions aren't explicitly specified anywhere. They 
 are
 just mentioned. You need some amount of guessing to find out what they are
 or how to create one (i.e. pass an empty list of store names).
>>>
>>> Yes, that has been a big problem for us too.
>>>
> Ah, I think I'm following you now. I'm actually not sure that we
> should have dynamic scope at all in the spec, I know Jeremy has
> expressed similar concerns. However if we are going to have dynamic
> scope, I agree it is a good idea to have separate APIs for starting
> dynamic-scope transactions from static-scope transactions.
>

 I think it would simplify matters a lot if we were to drop dynamic
 transactions altogether. And if we do that,  then we can also safely move
 the 'mode' to parameter to the Transaction interface, since all the object
 stores in a static transaction can be only be open in the same mode.
>>>
>>> Agreed.
>>>
> >> > 2. Provide a catalog object that can be used to atomically add/remove
> >> > object stores and indexes as well as modify version.
> >>
> >> It seems to me that a catalog object doesn't really provide any
> >> functionality over the proposal in bug 10052? The advantage that I see
> >> with the syntax proposal in bug 10052 is that it is simpler.
> >>
> >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
> >>
> >> Can you elaborate on what the advantages are of catalog objects?
> >
> > To begin with, 10052 shuts down the "users" of the database completely
> > when
> > only one is changing its structure, i.e., adding or removing an object
> > store.
>
> This is not the case. Check the steps defined for setVersion in [1].
> At no point are databases shut down automatically. Only once all
> existing database connections are manually closed, either by calls to
> IDBDatabase.close() or by the user leaving the page, is the 'success'
> event from setVersion fired.
>
> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>
> > How can we make it less draconian?
>
> The 'versionchange' event allows pages that are currently using the
> database to handle the change. The page can inspect the new version
> number supplied by the 'versionchange' event, and if it knows that it
> is compatible with a given upgrade, all it needs to do is to call
> db.close() and then immediately reopen the database using
> indexedDB.open(). The open call won't complete until the upgrade is
> finished.
>

 I had a question here: why does the page need to call 'close'?

Re: [IndexedDB] Current editor's draft

2010-07-08 Thread Jonas Sicking
On Thu, Jul 8, 2010 at 8:22 AM, Andrei Popescu  wrote:
> Hi Jonas,
>
> On Wed, Jul 7, 2010 at 8:08 PM, Jonas Sicking  wrote:
>> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>>>
>>>
>>> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:

 On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
 > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
 >>
 >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
 >> wrote:
 >> > Hi folks,
 >> >
 >> > There are several unimplemented proposals on strengthening and
 >> > expanding IndexedDB. The reason I have not implemented them yet is
 >> > because I am not convinced they are necessary in toto. Here's my
 >> > attempt at explaining why. I apologize in advance for not responding
 >> > to individual proposals due to personal time constraints. I will
 >> > however respond in detail on individual bug reports, e.g., as I did
 >> > with 9975.
 >> >
 >> > I used the current editor's draft asynchronous API to understand
 >> > where
 >> > some of the remaining programming difficulties remain. Based on this
 >> > attempt, I find several areas to strengthen, the most prominent of
 >> > which is how we use transactions. Another is to add the concept of a
 >> > catalog as a special kind of object store.
 >>
 >> Hi Nikunj,
 >>
 >> Thanks for replying! I'm very interested in getting this stuff sorted
 >> out pretty quickly as almost all other proposals in one way or another
 >> are affected by how this stuff develops.
 >>
 >> > Here are the main areas I propose to address in the editor's spec:
 >> >
 >> > 1. It is time to separate the dynamic and static scope transaction
 >> > creation so that they are asynchronous and synchronous respectively.
 >>
 >> I don't really understand what this means. What are dynamic and static
 >> scope transaction creation? Can you elaborate?
 >
 > This is the difference in the API in my email between openTransaction
 > and
 > transaction. Dynamic and static scope have been defined in the spec for
 > a
 > long time.

>>>
>>> In fact, dynamic transactions aren't explicitly specified anywhere. They are
>>> just mentioned. You need some amount of guessing to find out what they are
>>> or how to create one (i.e. pass an empty list of store names).
>>
>> Yes, that has been a big problem for us too.
>>
 Ah, I think I'm following you now. I'm actually not sure that we
 should have dynamic scope at all in the spec, I know Jeremy has
 expressed similar concerns. However if we are going to have dynamic
 scope, I agree it is a good idea to have separate APIs for starting
 dynamic-scope transactions from static-scope transactions.

>>>
>>> I think it would simplify matters a lot if we were to drop dynamic
>>> transactions altogether. And if we do that,  then we can also safely move
>>> the 'mode' to parameter to the Transaction interface, since all the object
>>> stores in a static transaction can be only be open in the same mode.
>>
>> Agreed.
>>
 >> > 2. Provide a catalog object that can be used to atomically add/remove
 >> > object stores and indexes as well as modify version.
 >>
 >> It seems to me that a catalog object doesn't really provide any
 >> functionality over the proposal in bug 10052? The advantage that I see
 >> with the syntax proposal in bug 10052 is that it is simpler.
 >>
 >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
 >>
 >> Can you elaborate on what the advantages are of catalog objects?
 >
 > To begin with, 10052 shuts down the "users" of the database completely
 > when
 > only one is changing its structure, i.e., adding or removing an object
 > store.

 This is not the case. Check the steps defined for setVersion in [1].
 At no point are databases shut down automatically. Only once all
 existing database connections are manually closed, either by calls to
 IDBDatabase.close() or by the user leaving the page, is the 'success'
 event from setVersion fired.

 [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0

 > How can we make it less draconian?

 The 'versionchange' event allows pages that are currently using the
 database to handle the change. The page can inspect the new version
 number supplied by the 'versionchange' event, and if it knows that it
 is compatible with a given upgrade, all it needs to do is to call
 db.close() and then immediately reopen the database using
 indexedDB.open(). The open call won't complete until the upgrade is
 finished.

>>>
>>> I had a question here: why does the page need to call 'close'? Any pending
>>> transactions will run to completion and new ones should not be allowed to
>>> start if a VERSION_CHANGE transaction is waiting to start. From the
>>> de

Re: [IndexedDB] Current editor's draft

2010-07-08 Thread Jonas Sicking
On Thu, Jul 8, 2010 at 8:22 AM, Andrei Popescu  wrote:
> Hi Jonas,
>
> On Wed, Jul 7, 2010 at 8:08 PM, Jonas Sicking  wrote:
>> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>>>
>>>
>>> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:

 On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
 > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
 >>
 >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
 >> wrote:
 >> > Hi folks,
 >> >
 >> > There are several unimplemented proposals on strengthening and
 >> > expanding IndexedDB. The reason I have not implemented them yet is
 >> > because I am not convinced they are necessary in toto. Here's my
 >> > attempt at explaining why. I apologize in advance for not responding
 >> > to individual proposals due to personal time constraints. I will
 >> > however respond in detail on individual bug reports, e.g., as I did
 >> > with 9975.
 >> >
 >> > I used the current editor's draft asynchronous API to understand
 >> > where
 >> > some of the remaining programming difficulties remain. Based on this
 >> > attempt, I find several areas to strengthen, the most prominent of
 >> > which is how we use transactions. Another is to add the concept of a
 >> > catalog as a special kind of object store.
 >>
 >> Hi Nikunj,
 >>
 >> Thanks for replying! I'm very interested in getting this stuff sorted
 >> out pretty quickly as almost all other proposals in one way or another
 >> are affected by how this stuff develops.
 >>
 >> > Here are the main areas I propose to address in the editor's spec:
 >> >
 >> > 1. It is time to separate the dynamic and static scope transaction
 >> > creation so that they are asynchronous and synchronous respectively.
 >>
 >> I don't really understand what this means. What are dynamic and static
 >> scope transaction creation? Can you elaborate?
 >
 > This is the difference in the API in my email between openTransaction
 > and
 > transaction. Dynamic and static scope have been defined in the spec for
 > a
 > long time.

>>>
>>> In fact, dynamic transactions aren't explicitly specified anywhere. They are
>>> just mentioned. You need some amount of guessing to find out what they are
>>> or how to create one (i.e. pass an empty list of store names).
>>
>> Yes, that has been a big problem for us too.
>>
 Ah, I think I'm following you now. I'm actually not sure that we
 should have dynamic scope at all in the spec, I know Jeremy has
 expressed similar concerns. However if we are going to have dynamic
 scope, I agree it is a good idea to have separate APIs for starting
 dynamic-scope transactions from static-scope transactions.

>>>
>>> I think it would simplify matters a lot if we were to drop dynamic
>>> transactions altogether. And if we do that,  then we can also safely move
>>> the 'mode' to parameter to the Transaction interface, since all the object
>>> stores in a static transaction can be only be open in the same mode.
>>
>> Agreed.
>>
 >> > 2. Provide a catalog object that can be used to atomically add/remove
 >> > object stores and indexes as well as modify version.
 >>
 >> It seems to me that a catalog object doesn't really provide any
 >> functionality over the proposal in bug 10052? The advantage that I see
 >> with the syntax proposal in bug 10052 is that it is simpler.
 >>
 >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
 >>
 >> Can you elaborate on what the advantages are of catalog objects?
 >
 > To begin with, 10052 shuts down the "users" of the database completely
 > when
 > only one is changing its structure, i.e., adding or removing an object
 > store.

 This is not the case. Check the steps defined for setVersion in [1].
 At no point are databases shut down automatically. Only once all
 existing database connections are manually closed, either by calls to
 IDBDatabase.close() or by the user leaving the page, is the 'success'
 event from setVersion fired.

 [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0

 > How can we make it less draconian?

 The 'versionchange' event allows pages that are currently using the
 database to handle the change. The page can inspect the new version
 number supplied by the 'versionchange' event, and if it knows that it
 is compatible with a given upgrade, all it needs to do is to call
 db.close() and then immediately reopen the database using
 indexedDB.open(). The open call won't complete until the upgrade is
 finished.

>>>
>>> I had a question here: why does the page need to call 'close'? Any pending
>>> transactions will run to completion and new ones should not be allowed to
>>> start if a VERSION_CHANGE transaction is waiting to start. From the
>>> de

Re: [IndexedDB] Current editor's draft

2010-07-08 Thread Andrei Popescu
Hi Jonas,

On Wed, Jul 7, 2010 at 8:08 PM, Jonas Sicking  wrote:
> On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>>
>>
>> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:
>>>
>>> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
>>> > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
>>> >>
>>> >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
>>> >> wrote:
>>> >> > Hi folks,
>>> >> >
>>> >> > There are several unimplemented proposals on strengthening and
>>> >> > expanding IndexedDB. The reason I have not implemented them yet is
>>> >> > because I am not convinced they are necessary in toto. Here's my
>>> >> > attempt at explaining why. I apologize in advance for not responding
>>> >> > to individual proposals due to personal time constraints. I will
>>> >> > however respond in detail on individual bug reports, e.g., as I did
>>> >> > with 9975.
>>> >> >
>>> >> > I used the current editor's draft asynchronous API to understand
>>> >> > where
>>> >> > some of the remaining programming difficulties remain. Based on this
>>> >> > attempt, I find several areas to strengthen, the most prominent of
>>> >> > which is how we use transactions. Another is to add the concept of a
>>> >> > catalog as a special kind of object store.
>>> >>
>>> >> Hi Nikunj,
>>> >>
>>> >> Thanks for replying! I'm very interested in getting this stuff sorted
>>> >> out pretty quickly as almost all other proposals in one way or another
>>> >> are affected by how this stuff develops.
>>> >>
>>> >> > Here are the main areas I propose to address in the editor's spec:
>>> >> >
>>> >> > 1. It is time to separate the dynamic and static scope transaction
>>> >> > creation so that they are asynchronous and synchronous respectively.
>>> >>
>>> >> I don't really understand what this means. What are dynamic and static
>>> >> scope transaction creation? Can you elaborate?
>>> >
>>> > This is the difference in the API in my email between openTransaction
>>> > and
>>> > transaction. Dynamic and static scope have been defined in the spec for
>>> > a
>>> > long time.
>>>
>>
>> In fact, dynamic transactions aren't explicitly specified anywhere. They are
>> just mentioned. You need some amount of guessing to find out what they are
>> or how to create one (i.e. pass an empty list of store names).
>
> Yes, that has been a big problem for us too.
>
>>> Ah, I think I'm following you now. I'm actually not sure that we
>>> should have dynamic scope at all in the spec, I know Jeremy has
>>> expressed similar concerns. However if we are going to have dynamic
>>> scope, I agree it is a good idea to have separate APIs for starting
>>> dynamic-scope transactions from static-scope transactions.
>>>
>>
>> I think it would simplify matters a lot if we were to drop dynamic
>> transactions altogether. And if we do that,  then we can also safely move
>> the 'mode' to parameter to the Transaction interface, since all the object
>> stores in a static transaction can be only be open in the same mode.
>
> Agreed.
>
>>> >> > 2. Provide a catalog object that can be used to atomically add/remove
>>> >> > object stores and indexes as well as modify version.
>>> >>
>>> >> It seems to me that a catalog object doesn't really provide any
>>> >> functionality over the proposal in bug 10052? The advantage that I see
>>> >> with the syntax proposal in bug 10052 is that it is simpler.
>>> >>
>>> >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>>> >>
>>> >> Can you elaborate on what the advantages are of catalog objects?
>>> >
>>> > To begin with, 10052 shuts down the "users" of the database completely
>>> > when
>>> > only one is changing its structure, i.e., adding or removing an object
>>> > store.
>>>
>>> This is not the case. Check the steps defined for setVersion in [1].
>>> At no point are databases shut down automatically. Only once all
>>> existing database connections are manually closed, either by calls to
>>> IDBDatabase.close() or by the user leaving the page, is the 'success'
>>> event from setVersion fired.
>>>
>>> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>>>
>>> > How can we make it less draconian?
>>>
>>> The 'versionchange' event allows pages that are currently using the
>>> database to handle the change. The page can inspect the new version
>>> number supplied by the 'versionchange' event, and if it knows that it
>>> is compatible with a given upgrade, all it needs to do is to call
>>> db.close() and then immediately reopen the database using
>>> indexedDB.open(). The open call won't complete until the upgrade is
>>> finished.
>>>
>>
>> I had a question here: why does the page need to call 'close'? Any pending
>> transactions will run to completion and new ones should not be allowed to
>> start if a VERSION_CHANGE transaction is waiting to start. From the
>> description of what 'close' does in 10052, I am not entirely sure it is
>> needed.
>
> The problem we're trying to solve is this:
>
> Imagine an editor which stores docu

Re: [IndexedDB] Current editor's draft

2010-07-07 Thread Shawn Wilsher

 On 7/7/2010 12:27 AM, Jonas Sicking wrote:

This interface allows asynchronously requesting more objectStores to
be locked. The author must take care whenever calling openObjectStores
that the request might fail due to deadlocks.

But as previously stated, I think this adds too much complexity and
too much racyness to the API. And so I'd prefer to not add this.
I feel like we should not be creating an API that allows for deadlocks 
to happen.  Especially with an API that allows for races to happen 
(which we have) such that it will be hard for web developers to test to 
ensure they do not have deadlocks.


Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Current editor's draft

2010-07-07 Thread Shawn Wilsher

 On 7/6/2010 6:31 PM, Nikunj Mehta wrote:

To begin with, 10052 shuts down the "users" of the database completely when
only one is changing its structure, i.e., adding or removing an object
store. How can we make it less draconian? Secondly, I don't see how that
approach can produce atomic changes to the database. Thirdly, we shouldn't
need to change version in order to perform database changes. Finally, I am
not sure why you consider the syntax proposal simpler. Note that I am not
averse to the version change event notification.
In what use case would you want to change the database structure without 
modifying the version?  That almost seems like a footgun for consumers.



Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Current editor's draft

2010-07-07 Thread Jonas Sicking
On Wed, Jul 7, 2010 at 10:41 AM, Andrei Popescu  wrote:
>
>
> On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:
>>
>> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
>> > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
>> >>
>> >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
>> >> wrote:
>> >> > Hi folks,
>> >> >
>> >> > There are several unimplemented proposals on strengthening and
>> >> > expanding IndexedDB. The reason I have not implemented them yet is
>> >> > because I am not convinced they are necessary in toto. Here's my
>> >> > attempt at explaining why. I apologize in advance for not responding
>> >> > to individual proposals due to personal time constraints. I will
>> >> > however respond in detail on individual bug reports, e.g., as I did
>> >> > with 9975.
>> >> >
>> >> > I used the current editor's draft asynchronous API to understand
>> >> > where
>> >> > some of the remaining programming difficulties remain. Based on this
>> >> > attempt, I find several areas to strengthen, the most prominent of
>> >> > which is how we use transactions. Another is to add the concept of a
>> >> > catalog as a special kind of object store.
>> >>
>> >> Hi Nikunj,
>> >>
>> >> Thanks for replying! I'm very interested in getting this stuff sorted
>> >> out pretty quickly as almost all other proposals in one way or another
>> >> are affected by how this stuff develops.
>> >>
>> >> > Here are the main areas I propose to address in the editor's spec:
>> >> >
>> >> > 1. It is time to separate the dynamic and static scope transaction
>> >> > creation so that they are asynchronous and synchronous respectively.
>> >>
>> >> I don't really understand what this means. What are dynamic and static
>> >> scope transaction creation? Can you elaborate?
>> >
>> > This is the difference in the API in my email between openTransaction
>> > and
>> > transaction. Dynamic and static scope have been defined in the spec for
>> > a
>> > long time.
>>
>
> In fact, dynamic transactions aren't explicitly specified anywhere. They are
> just mentioned. You need some amount of guessing to find out what they are
> or how to create one (i.e. pass an empty list of store names).

Yes, that has been a big problem for us too.

>> Ah, I think I'm following you now. I'm actually not sure that we
>> should have dynamic scope at all in the spec, I know Jeremy has
>> expressed similar concerns. However if we are going to have dynamic
>> scope, I agree it is a good idea to have separate APIs for starting
>> dynamic-scope transactions from static-scope transactions.
>>
>
> I think it would simplify matters a lot if we were to drop dynamic
> transactions altogether. And if we do that,  then we can also safely move
> the 'mode' to parameter to the Transaction interface, since all the object
> stores in a static transaction can be only be open in the same mode.

Agreed.

>> >> > 2. Provide a catalog object that can be used to atomically add/remove
>> >> > object stores and indexes as well as modify version.
>> >>
>> >> It seems to me that a catalog object doesn't really provide any
>> >> functionality over the proposal in bug 10052? The advantage that I see
>> >> with the syntax proposal in bug 10052 is that it is simpler.
>> >>
>> >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>> >>
>> >> Can you elaborate on what the advantages are of catalog objects?
>> >
>> > To begin with, 10052 shuts down the "users" of the database completely
>> > when
>> > only one is changing its structure, i.e., adding or removing an object
>> > store.
>>
>> This is not the case. Check the steps defined for setVersion in [1].
>> At no point are databases shut down automatically. Only once all
>> existing database connections are manually closed, either by calls to
>> IDBDatabase.close() or by the user leaving the page, is the 'success'
>> event from setVersion fired.
>>
>> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>>
>> > How can we make it less draconian?
>>
>> The 'versionchange' event allows pages that are currently using the
>> database to handle the change. The page can inspect the new version
>> number supplied by the 'versionchange' event, and if it knows that it
>> is compatible with a given upgrade, all it needs to do is to call
>> db.close() and then immediately reopen the database using
>> indexedDB.open(). The open call won't complete until the upgrade is
>> finished.
>>
>
> I had a question here: why does the page need to call 'close'? Any pending
> transactions will run to completion and new ones should not be allowed to
> start if a VERSION_CHANGE transaction is waiting to start. From the
> description of what 'close' does in 10052, I am not entirely sure it is
> needed.

The problem we're trying to solve is this:

Imagine an editor which stores documents in indexedDB. However in
order to not overwrite the document using temporary changes, it only
saves data when the user explicitly requests it, for example by
pressing a 'save' 

Re: [IndexedDB] Current editor's draft

2010-07-07 Thread Andrei Popescu
On Wed, Jul 7, 2010 at 8:27 AM, Jonas Sicking  wrote:

> On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
> > On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
> >>
> >> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta 
> wrote:
> >> > Hi folks,
> >> >
> >> > There are several unimplemented proposals on strengthening and
> >> > expanding IndexedDB. The reason I have not implemented them yet is
> >> > because I am not convinced they are necessary in toto. Here's my
> >> > attempt at explaining why. I apologize in advance for not responding
> >> > to individual proposals due to personal time constraints. I will
> >> > however respond in detail on individual bug reports, e.g., as I did
> >> > with 9975.
> >> >
> >> > I used the current editor's draft asynchronous API to understand where
> >> > some of the remaining programming difficulties remain. Based on this
> >> > attempt, I find several areas to strengthen, the most prominent of
> >> > which is how we use transactions. Another is to add the concept of a
> >> > catalog as a special kind of object store.
> >>
> >> Hi Nikunj,
> >>
> >> Thanks for replying! I'm very interested in getting this stuff sorted
> >> out pretty quickly as almost all other proposals in one way or another
> >> are affected by how this stuff develops.
> >>
> >> > Here are the main areas I propose to address in the editor's spec:
> >> >
> >> > 1. It is time to separate the dynamic and static scope transaction
> >> > creation so that they are asynchronous and synchronous respectively.
> >>
> >> I don't really understand what this means. What are dynamic and static
> >> scope transaction creation? Can you elaborate?
> >
> > This is the difference in the API in my email between openTransaction and
> > transaction. Dynamic and static scope have been defined in the spec for a
> > long time.
>
>
In fact, dynamic transactions aren't explicitly specified anywhere. They are
just mentioned. You need some amount of guessing to find out what they are
or how to create one (i.e. pass an empty list of store names).


> Ah, I think I'm following you now. I'm actually not sure that we
> should have dynamic scope at all in the spec, I know Jeremy has
> expressed similar concerns. However if we are going to have dynamic
> scope, I agree it is a good idea to have separate APIs for starting
> dynamic-scope transactions from static-scope transactions.
>
>
I think it would simplify matters a lot if we were to drop dynamic
transactions altogether. And if we do that,  then we can also safely move
the 'mode' to parameter to the Transaction interface, since all the object
stores in a static transaction can be only be open in the same mode.


> >> > 2. Provide a catalog object that can be used to atomically add/remove
> >> > object stores and indexes as well as modify version.
> >>
> >> It seems to me that a catalog object doesn't really provide any
> >> functionality over the proposal in bug 10052? The advantage that I see
> >> with the syntax proposal in bug 10052 is that it is simpler.
> >>
> >> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
> >>
> >> Can you elaborate on what the advantages are of catalog objects?
> >
> > To begin with, 10052 shuts down the "users" of the database completely
> when
> > only one is changing its structure, i.e., adding or removing an object
> > store.
>
> This is not the case. Check the steps defined for setVersion in [1].
> At no point are databases shut down automatically. Only once all
> existing database connections are manually closed, either by calls to
> IDBDatabase.close() or by the user leaving the page, is the 'success'
> event from setVersion fired.
>
> [1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0
>
> > How can we make it less draconian?
>
> The 'versionchange' event allows pages that are currently using the
> database to handle the change. The page can inspect the new version
> number supplied by the 'versionchange' event, and if it knows that it
> is compatible with a given upgrade, all it needs to do is to call
> db.close() and then immediately reopen the database using
> indexedDB.open(). The open call won't complete until the upgrade is
> finished.
>
>
I had a question here: why does the page need to call 'close'? Any pending
transactions will run to completion and new ones should not be allowed to
start if a VERSION_CHANGE transaction is waiting to start. From the
description of what 'close' does in 10052, I am not entirely sure it is
needed.


> > Secondly, I don't see how that
> > approach can produce atomic changes to the database.
>
> When the transaction created in step 4 of setVersion defined in [1] is
> created, only one IDBDatabase object to the database is open. As long
> as that transaction is running, no requests returned from
> IDBFactory.open will receive a 'success' event. Only once the
> transaction is committed, or aborted, will those requests succeed.
> This guarantees that no other IDBDatabase object can see a partial
> 

Re: [IndexedDB] Current editor's draft

2010-07-07 Thread Jonas Sicking
On Tue, Jul 6, 2010 at 6:31 PM, Nikunj Mehta  wrote:
> On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:
>>
>> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta  wrote:
>> > Hi folks,
>> >
>> > There are several unimplemented proposals on strengthening and
>> > expanding IndexedDB. The reason I have not implemented them yet is
>> > because I am not convinced they are necessary in toto. Here's my
>> > attempt at explaining why. I apologize in advance for not responding
>> > to individual proposals due to personal time constraints. I will
>> > however respond in detail on individual bug reports, e.g., as I did
>> > with 9975.
>> >
>> > I used the current editor's draft asynchronous API to understand where
>> > some of the remaining programming difficulties remain. Based on this
>> > attempt, I find several areas to strengthen, the most prominent of
>> > which is how we use transactions. Another is to add the concept of a
>> > catalog as a special kind of object store.
>>
>> Hi Nikunj,
>>
>> Thanks for replying! I'm very interested in getting this stuff sorted
>> out pretty quickly as almost all other proposals in one way or another
>> are affected by how this stuff develops.
>>
>> > Here are the main areas I propose to address in the editor's spec:
>> >
>> > 1. It is time to separate the dynamic and static scope transaction
>> > creation so that they are asynchronous and synchronous respectively.
>>
>> I don't really understand what this means. What are dynamic and static
>> scope transaction creation? Can you elaborate?
>
> This is the difference in the API in my email between openTransaction and
> transaction. Dynamic and static scope have been defined in the spec for a
> long time.

Ah, I think I'm following you now. I'm actually not sure that we
should have dynamic scope at all in the spec, I know Jeremy has
expressed similar concerns. However if we are going to have dynamic
scope, I agree it is a good idea to have separate APIs for starting
dynamic-scope transactions from static-scope transactions.

>> > 2. Provide a catalog object that can be used to atomically add/remove
>> > object stores and indexes as well as modify version.
>>
>> It seems to me that a catalog object doesn't really provide any
>> functionality over the proposal in bug 10052? The advantage that I see
>> with the syntax proposal in bug 10052 is that it is simpler.
>>
>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>>
>> Can you elaborate on what the advantages are of catalog objects?
>
> To begin with, 10052 shuts down the "users" of the database completely when
> only one is changing its structure, i.e., adding or removing an object
> store.

This is not the case. Check the steps defined for setVersion in [1].
At no point are databases shut down automatically. Only once all
existing database connections are manually closed, either by calls to
IDBDatabase.close() or by the user leaving the page, is the 'success'
event from setVersion fired.

[1] http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052#c0

> How can we make it less draconian?

The 'versionchange' event allows pages that are currently using the
database to handle the change. The page can inspect the new version
number supplied by the 'versionchange' event, and if it knows that it
is compatible with a given upgrade, all it needs to do is to call
db.close() and then immediately reopen the database using
indexedDB.open(). The open call won't complete until the upgrade is
finished.

> Secondly, I don't see how that
> approach can produce atomic changes to the database.

When the transaction created in step 4 of setVersion defined in [1] is
created, only one IDBDatabase object to the database is open. As long
as that transaction is running, no requests returned from
IDBFactory.open will receive a 'success' event. Only once the
transaction is committed, or aborted, will those requests succeed.
This guarantees that no other IDBDatabase object can see a partial
update.

Further, only once the transaction created by setVersion is committed,
are the requested objectStores and indexes created/removed. This
guarantees that the database is never left with a partial update.

That means that the changes are atomic, right?

> Thirdly, we shouldn't
> need to change version in order to perform database changes.

First off, note that if the upgrade is compatible, you can just pass
the existing database version to setVersion. So no version *change* is
actually needed.

Second, I don't think there is much difference between

var txn = db.transaction();
db.openCatalog(txn).onsuccess = ...

vs

db.setVersion("5").onsuccess = ...

I don't see that telling people that they have to use the former is a big win.


The problem that I see with the catalog proposal, if I understand it
correctly, is that it means that a page that has a IDBDatabase object
open has to always be prepared for calls to
openObjectStore/openTransaction failing. I.e. the page can't ever know
that another page was opened whi

Re: [IndexedDB] Current editor's draft

2010-07-06 Thread Nikunj Mehta
On Wed, Jul 7, 2010 at 5:57 AM, Jonas Sicking  wrote:

> On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta  wrote:
> > Hi folks,
> >
> > There are several unimplemented proposals on strengthening and
> > expanding IndexedDB. The reason I have not implemented them yet is
> > because I am not convinced they are necessary in toto. Here's my
> > attempt at explaining why. I apologize in advance for not responding
> > to individual proposals due to personal time constraints. I will
> > however respond in detail on individual bug reports, e.g., as I did
> > with 9975.
> >
> > I used the current editor's draft asynchronous API to understand where
> > some of the remaining programming difficulties remain. Based on this
> > attempt, I find several areas to strengthen, the most prominent of
> > which is how we use transactions. Another is to add the concept of a
> > catalog as a special kind of object store.
>
> Hi Nikunj,
>
> Thanks for replying! I'm very interested in getting this stuff sorted
> out pretty quickly as almost all other proposals in one way or another
> are affected by how this stuff develops.
>
> > Here are the main areas I propose to address in the editor's spec:
> >
> > 1. It is time to separate the dynamic and static scope transaction
> > creation so that they are asynchronous and synchronous respectively.
>
> I don't really understand what this means. What are dynamic and static
> scope transaction creation? Can you elaborate?
>

This is the difference in the API in my email between openTransaction and
transaction. Dynamic and static scope have been defined in the spec for a
long time.


>
> > 2. Provide a catalog object that can be used to atomically add/remove
> > object stores and indexes as well as modify version.
>
> It seems to me that a catalog object doesn't really provide any
> functionality over the proposal in bug 10052? The advantage that I see
> with the syntax proposal in bug 10052 is that it is simpler.
>
> http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052
>
> Can you elaborate on what the advantages are of catalog objects?
>

To begin with, 10052 shuts down the "users" of the database completely when
only one is changing its structure, i.e., adding or removing an object
store. How can we make it less draconian? Secondly, I don't see how that
approach can produce atomic changes to the database. Thirdly, we shouldn't
need to change version in order to perform database changes. Finally, I am
not sure why you consider the syntax proposal simpler. Note that I am not
averse to the version change event notification.

> 3.  Cursors may produce a null key or a null value. I don't see how
> > this is valid signaling for non-preloaded cursors. I think we need to
> > add a new flag on the cursor to find out if the cursor is exhausted.
>
> Our proposal was that IDBEvent.result would normally contain the
> cursor object, but once the end is reached it returns null. To be
> clear:
>
> When a value is found:
> event.result;   // returns cursor object, never null
> event.result.key;  // returns key, may be null
> event.result.value;  // returns value, may be null
>
> When end is reached:
> event.result;  // returns null
>
>
Got it. I will try out this approach.


>
> > A couple of additional points:
> >
> > 1. I did not see any significant benefits of preloaded cursors in
> > terms of programming ease.
>
> Yes, there seems to be agreement that preloaded cursors should be
> removed. I've removed them from our proposal.
>
> > 2. *_NO_DUPLICATE simplifies programming as well as aids in good
> > performance. I have shown one example that illustrates this.
>
> I'll have to analyze the examples below. My gut instinct though is
> that I agree with you that they are needed.
>
> > 3. Since it seems continue is acceptable to implementers, I am also
> > suggesting we use delete instead of remove, for consistency sake.
>
> Agreed.
>
> > --- IDL 
> >
> > [NoInterfaceObject]
> > interface IDBDatabase {
> >  readonly attribute DOMString name;
> >  readonly attribute DOMString description;
> >  readonly attribute DOMStringList objectStores;
> >  /*
> >  Open an object store in the specified transaction. The transaction can
> be
> >  dynamic scoped, or the requested object store must be in the static
> scope.
> >  Returns IDBRequest whose success event of IDBTransactionEvent type
> contains
> >  a result with IDBObjectStore and transaction is an
> IDBTransactionRequest.
> >  */
> >  IDBRequest openObjectStore(in DOMString name, in IDBTransaction txn,
> >  in optional unsigned short mode /* defaults to READ_WRITE */);
>
> I don't understand the advantage of this proposal over mozillas
> proposal.


The above proposal allows opening multiple object stores in the same
transaction in dynamic scope, even without having explicitly identified each
one of them at the time of creating the transaction. Secondly, where static
scope is desired, in order to run to completion without being aborted due to
unava

Re: [IndexedDB] Current editor's draft

2010-07-06 Thread Jonas Sicking
On Tue, Jul 6, 2010 at 9:36 AM, Nikunj Mehta  wrote:
> Hi folks,
>
> There are several unimplemented proposals on strengthening and
> expanding IndexedDB. The reason I have not implemented them yet is
> because I am not convinced they are necessary in toto. Here's my
> attempt at explaining why. I apologize in advance for not responding
> to individual proposals due to personal time constraints. I will
> however respond in detail on individual bug reports, e.g., as I did
> with 9975.
>
> I used the current editor's draft asynchronous API to understand where
> some of the remaining programming difficulties remain. Based on this
> attempt, I find several areas to strengthen, the most prominent of
> which is how we use transactions. Another is to add the concept of a
> catalog as a special kind of object store.

Hi Nikunj,

Thanks for replying! I'm very interested in getting this stuff sorted
out pretty quickly as almost all other proposals in one way or another
are affected by how this stuff develops.

> Here are the main areas I propose to address in the editor's spec:
>
> 1. It is time to separate the dynamic and static scope transaction
> creation so that they are asynchronous and synchronous respectively.

I don't really understand what this means. What are dynamic and static
scope transaction creation? Can you elaborate?

> 2. Provide a catalog object that can be used to atomically add/remove
> object stores and indexes as well as modify version.

It seems to me that a catalog object doesn't really provide any
functionality over the proposal in bug 10052? The advantage that I see
with the syntax proposal in bug 10052 is that it is simpler.

http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052

Can you elaborate on what the advantages are of catalog objects?

> 3.  Cursors may produce a null key or a null value. I don't see how
> this is valid signaling for non-preloaded cursors. I think we need to
> add a new flag on the cursor to find out if the cursor is exhausted.

Our proposal was that IDBEvent.result would normally contain the
cursor object, but once the end is reached it returns null. To be
clear:

When a value is found:
event.result;   // returns cursor object, never null
event.result.key;  // returns key, may be null
event.result.value;  // returns value, may be null

When end is reached:
event.result;  // returns null


> A couple of additional points:
>
> 1. I did not see any significant benefits of preloaded cursors in
> terms of programming ease.

Yes, there seems to be agreement that preloaded cursors should be
removed. I've removed them from our proposal.

> 2. *_NO_DUPLICATE simplifies programming as well as aids in good
> performance. I have shown one example that illustrates this.

I'll have to analyze the examples below. My gut instinct though is
that I agree with you that they are needed.

> 3. Since it seems continue is acceptable to implementers, I am also
> suggesting we use delete instead of remove, for consistency sake.

Agreed.

> --- IDL 
>
> [NoInterfaceObject]
> interface IDBDatabase {
>  readonly attribute DOMString     name;
>  readonly attribute DOMString     description;
>  readonly attribute DOMStringList objectStores;
>  /*
>  Open an object store in the specified transaction. The transaction can be
>  dynamic scoped, or the requested object store must be in the static scope.
>  Returns IDBRequest whose success event of IDBTransactionEvent type contains
>  a result with IDBObjectStore and transaction is an IDBTransactionRequest.
>  */
>  IDBRequest openObjectStore(in DOMString name, in IDBTransaction txn,
>  in optional unsigned short mode /* defaults to READ_WRITE */);

I don't understand the advantage of this proposal over mozillas
proposal. One of our main points was to make getting objectStore
objects a synchronous operation as to avoid having to nest multiple
levels of asynchronous calls. Compare

var req = db.openObjectStore("foo", trans);
req.onerror = errorHandler;
req.onsuccess = function(e) {
  var fooStore = e.result;
  var req = fooStore.get(12);
  req.onerror = errorHandler;
  req.onsuccess = resultHandler;
}

to

var fooStore = db.openObjectStore("foo", trans);
var req = fooStore.get(12);
req.onerror = errorHandler;
req.onsuccess = resultHandler;


I also don't understand the advantage of having the transaction as an
argument to openObjectStore rather than having openObjectStore live on
transaction. Compare

db.openObjectStore("foo", trans);

to

trans.openObjectStore("foo");

I also don't understand the meaning of specifying a mode when a
objectStore is opened, rather than specifying the mode when the
transaction is created. Unless we're planning on making all
transactions dynamic (I hope not), locks have to be grabbed when the
transaction is created, right? If a transaction is holding a READ_ONLY
lock for a given objectStore, then attempting to open that objectStore
as READ_WRITE should obviously fail. Consecutively, if a transaction
is holdin