Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 337870

Summary: Provide durable locking
Product: [Modeling] EMF Reporter: Stephane fournier <stephane.fournier>
Component: cdo.coreAssignee: Eike Stepper <stepper>
Status: CLOSED FIXED QA Contact: Eike Stepper <stepper>
Severity: enhancement    
Priority: P3 CC: alex.lagarde, caspar_d, mariot.chauvin, saulius.tvarijonas, stepper
Version: 4.0   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Patch v1
none
Patch v2
none
Patch v3 none

Description Stephane fournier CLA 2011-02-22 13:01:41 EST
Build Identifier: CDO 4.0.0

Client side
1.	CDO shall provide a way to maintain locked (read / write) objects even if the CDOView is closed. These locks are considered as "long lasting locks" or "permanent locks".
2.	CDO shall provide a way to resume a CDOView and retrieve the previous "long lasting locks" in order to release them implicitely through a commit or rollback or explicitely through unlockObjects.
Client or server side
3.	CDO shall provide a way to release "long lasting locks" from an "administration" operation. An API is needed (from client or server side?) to implement such a service in an administration tool.
4.	CDO shall provide a way to identify long lasting locks vs. standard locks easily to help the implementation of the administration tool. What about a boolean attribute on Lock meaning long lasting?
Use cases highlighting these needs
Use case 1
	An end-user locks some objects before disconnecting from the repository to work offline. He wants to avoid other end-users to modify the objects in the meanwhile (the ones he locks). When he will come back either he will commit its changes and release the long lasting locks or he will simply release its locks.
Use case 2
	An end-user Foo locks some objects and goes offline and never reconnects. Hence, the administration user, from an administration tool (running as client or on server side?), has to release the pending long lasting locks held by the end-user Foo.


Reproducible: Always

Steps to Reproduce:
See details.
Comment 1 Caspar D. CLA 2011-02-22 22:11:17 EST
(In reply to comment #0)

I proposed the same thing 2 years ago: bug 276063. At the time
there was "a bit" of resistance against the concept, and I was
"encouraged" to rewrite the idea as part of an access control
system -- something it can but does not have to be part of.

A few important things that are not quite explicit in your description,
are:
(1) that a "long-lasting lock", as you call it, does not prevent
the locked object from being *read* by other users -- while a traditional
write lock does;
(2) that only 1 user can put a long-lasting lock on an object
(3) that only that user can write the object

To avoid confusion, and the endless misguided debates that we had in
2009, it might be wise to call these locks "reservations" or something.
As I've stated before, the concept is entirely analogous to 'svn lock'
and 'cvs edit', and has very little to do with traditional locks
in the reader-writer paradigm. (The current CDO locks are of the latter
kind.)

> What about a boolean attribute on Lock meaning long lasting

I'd rather see the concepts disentangled altogether. The existing CDO
locks are a concurrency-control solution. The kind of lock you are
proposing is not about concurrency control, but about obtaining a
semi-permanent exclusive access right to write a particular object.
(Hence the possible integration into an ACL framework -- but I 
prefer to consider them separate features, contrary to what that
old Bugzilla of mine proposes.)

To put it differently, these "long-lasting locks"/reservations cannot
be realized by making the existing read/write locks persist across
client sessions (or even across server restarts), simply because
their semantics are distinct from both the existing read locks and
the existing write locks, and serve a different purpose.
Comment 2 Stephane fournier CLA 2011-02-24 07:05:46 EST
(In reply to comment #1)
> (In reply to comment #0)
> 
> I proposed the same thing 2 years ago: bug 276063. At the time
> there was "a bit" of resistance against the concept, and I was
> "encouraged" to rewrite the idea as part of an access control
> system -- something it can but does not have to be part of.

2 years ago, CDO did not provide an offline mode because 'C' means connected ;o)

> 
> A few important things that are not quite explicit in your description,
> are:
> (1) that a "long-lasting lock", as you call it, does not prevent
> the locked object from being *read* by other users -- while a traditional
> write lock does;
> (2) that only 1 user can put a long-lasting lock on an object
> (3) that only that user can write the object
> 
From my point of view, long lasting locks can be read locks or write locks.
'Long lasting' means the lock is not released when the CDOView is closed.

> To avoid confusion, and the endless misguided debates that we had in
> 2009, it might be wise to call these locks "reservations" or something.
> As I've stated before, the concept is entirely analogous to 'svn lock'
> and 'cvs edit', and has very little to do with traditional locks
> in the reader-writer paradigm. (The current CDO locks are of the latter
> kind.)
> 
Long lasting locks shall behave as existing CDO locks.If an user A takes a Write Long Lasting lock on an object, no one else can take a lock on the same object whatever the lock type is.

If an user A takes a Read long lasting lock on an object, no else can take a write lock but read locks are allowed.

That's why we need an API to be able to force unlock for long lasting locks.

> > What about a boolean attribute on Lock meaning long lasting
> 
> I'd rather see the concepts disentangled altogether. The existing CDO
> locks are a concurrency-control solution. The kind of lock you are
> proposing is not about concurrency control, but about obtaining a
> semi-permanent exclusive access right to write a particular object.
> (Hence the possible integration into an ACL framework -- but I 
> prefer to consider them separate features, contrary to what that
> old Bugzilla of mine proposes.)
>
I disagree with that, long lasting locks and standard locks have the same purpose as explained above.
 
> To put it differently, these "long-lasting locks"/reservations cannot
> be realized by making the existing read/write locks persist across
> client sessions (or even across server restarts), simply because
> their semantics are distinct from both the existing read locks and
> the existing write locks, and serve a different purpose.
Comment 3 Eike Stepper CLA 2011-02-24 10:00:30 EST
Stephane, I agree with Caspar here. As far as I know you want to reserve the right to modify an object in the future, but until you will actually acquire a write lock then you probably don't want to prevent others from reading that object. Hence yu can't use write lock semantics. As you mentioned you could try to hold a read lock to prevent others from writing until you are ready to do your own write. But the escalation from the read lock you're holding to the write lock you'll want to hold later is not guaranteed to ever work. Others could hold long lasting read locks as well to declare their intent to escalate to a write lock later. Nobody will ever be able do do so however.
Comment 4 Eike Stepper CLA 2011-04-11 00:08:30 EDT
Thinking about it once more, I withdraw my initial consent with Caspar's argument.

In that discussion we've missed an important point: Holding a read lock is not identical (not even a precondition) to being able to read an object.

If I understand the original request right the requirement is that others can read an object while there's a long lasting write lock on it, not that others can put read locks on it.

Can we agree that these are the intended semantics and that persisting the existing lock information across sessions and server restarts is the way to implement this functionality?
Comment 5 Caspar D. CLA 2011-04-18 02:40:01 EDT
(In reply to comment #4)
> In that discussion we've missed an important point: Holding a read lock is not
> identical (not even a precondition) to being able to read an object.

We discussed this extensively on Skype, but for the record: I considered the above (i.e. the ability to read a revision while someone has a write-lock on it) to be a loophole rather than a feature. But if we consider it "intended behavior"
then indeed my argument is largely invalidated. This interpretation/use of our
locks comes at a price though: weird semantics. A write lock is no longer a
means of preventing other reads, and readLocks are really antiwriteLocks (term
courtesy of Eike) with no relevance to normal reading. This means our read/write
locks are not a solution to the standard readers-writers concurrency problem,
which was what I thought (based on how they've been implemented) they were
meant to be.
Comment 6 Eike Stepper CLA 2011-05-10 05:49:30 EDT
Created attachment 195189 [details]
Patch v1

Hi Stephane, Here comes a functional implementation. Please test it and check if it matches your expectations. Let me know if you have any questions or comments.
Comment 7 Eike Stepper CLA 2011-05-10 05:51:30 EDT
- All client side API is implemented as spec'ed.
- Network protocol is adjusted.
- Server API is implemented as spec'ed.
- Support for MEMStore and DBStore has been added.
- I've added console commands for the admin.
- I've integrated te functionality into the generic UI.
- I've written 17 test cases that are executed in 3 different restart scenarios.

Here is a real dump from the OSGi console:

osgi> help
---Net4j commands---
    elements - list all managed elements
    acceptors - list all active acceptors, their connectors and channels
    connectors - list all active connectors and their channels
---CDO commands---
    cdo list - list all active repositories
    cdo start - start repositories from a config file
    cdo stop - stop a repository
    cdo export - export the contents of a repository to an XML file
    cdo import - import the contents of a repository from an XML file
    cdo sessions - dump the sessions of a repository
    cdo packages - dump the packages of a repository
    cdo branches - dump the branches of a repository
    cdo locks - dump the durable locking areas of a repository
    cdo deletelocks - delete a durable locking area of a repository

osgi> cdo locks
Syntax: cdo locks <repository-name> [<username-prefix>]

osgi> cdo locks repo1
0abc8deda4bf25e5f0e9f5be628d8713ddc5f1480506002684a1ea80beaeec31
  userID = null
  branch = Branch[id=0, name=MAIN]
  timeStamp = *
  readOnly = false
  locks = {OID5=WRITE, OID4=WRITE, OID7=READ, OID6=WRITE, OID8=READ}
c8a7be63dea279b47bc4c990dc348169f38207256cf7323f326f8541e094aeca
  userID = null
  branch = Branch[id=0, name=MAIN]
  timeStamp = *
  readOnly = false
  locks = {OID9=WRITE, OID10=WRITE}

osgi> cdo deletelocks
Syntax: cdo deletelocks <repository-name> <area-id>

osgi> cdo deletelocks repo1 0abc8deda4bf25e5f0e9f5be628d8713ddc5f1480506002684a1ea80beaeec31
OSGi Console [debug.sql] prep33: DELETE FROM cdo_locks WHERE area_id=? {1: '0abc8deda4bf25e5f0e9f5be628d8713ddc5f1480506002684a1ea80beaeec31'};
OSGi Console [debug.sql] prep34: DELETE FROM cdo_lock_areas WHERE id=? {1: '0abc8deda4bf25e5f0e9f5be628d8713ddc5f1480506002684a1ea80beaeec31'};

osgi> cdo locks repo1
c8a7be63dea279b47bc4c990dc348169f38207256cf7323f326f8541e094aeca
  userID = null
  branch = Branch[id=0, name=MAIN]
  timeStamp = *
  readOnly = false
  locks = {OID9=WRITE, OID10=WRITE}
Comment 8 Eike Stepper CLA 2011-05-16 12:14:58 EDT
Created attachment 195755 [details]
Patch v2

Re-integrated with HEAD
Comment 9 Eike Stepper CLA 2011-05-16 12:55:26 EDT
Created attachment 195760 [details]
Patch v3

v2 was missing some changes in TransactionCommitContext due to conflicts that had to be merged manually.
Comment 10 Eike Stepper CLA 2011-05-16 13:02:49 EDT
Committed revision 7734
Comment 11 Eike Stepper CLA 2011-05-16 13:05:34 EDT
Committed revision 7736
Comment 12 Eike Stepper CLA 2011-05-17 07:09:34 EDT
Committed revision 7762:
- trunk/plugins/org.eclipse.emf.cdo.server
Comment 13 Eike Stepper CLA 2011-05-26 04:46:52 EDT
Committed revision 7850:
- trunk/plugins/org.eclipse.emf.cdo.server
Comment 14 Eike Stepper CLA 2011-06-23 04:30:26 EDT
Moving all open enhancement requests to 4.1
Comment 15 Eike Stepper CLA 2011-07-06 02:47:34 EDT
Reverting the previous status change which was accidental.
Comment 16 Eike Stepper CLA 2012-09-21 06:52:11 EDT
Closing.