RFC: Lightblue synchronization primitives

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

RFC: Lightblue synchronization primitives

bserdar
There appears to be a need to provide operations that guarantee atomicity and mutual exclusion at the core library level. The migrator uses a locking mechanism, esb mediator is planning to use that as well, and it would probably be useful going forward in implementing transaction support. This is a proposal that describes how we can add mutual exclusion operations at the core level.

Data types:
  - domain: The name of the backend and datastore that implements the synchronization mechanism. Available domains are configured and registered to the lightblue instance. For instance, a MongoDB implementation of synchronization primitives would specify the backend "mongo" with the name of the datasource to keep the synchronization data.
  - callerId: A value that uniquely identifies the caller. This can be java.util.UUID.randomUUID()
  - resourceId: A logical identifier of the resource. If the resource is a document in the database, this may be "entityName:uniqueId"

Proposed APIs:

   acquire(callerId,resourceId,domain [,ttl])

Atomically acquire the resource for the caller. Fails if the resource is already acquired by another caller. Subsequent calls to acquire using the same callerId will require matching release calls. Optional ttl determines the timeout for the acquisition. If the mutex is acquired without any ping for ttl amount of time, the lock is released.


   release(callerId, resourceId,domain)

Releases the resource. If there are n calls to lock the same resource by the same caller, n calls to release by the same caller is required to release the resource.

   isAcquired(callerId,resourceId,domain)

Returns true if the resource is acquired by the caller.

   ping(callerId, resourceId,domain)

Update the mutex timestamp, so it would not expire.

Implementation:

Configuration subsystem: Need to add support for synchronization domain registration. Initially we will implement this for mongo subsystem only, and the synchronization domain should look like this:

    "mongo" : {
             "backend":"mongo",
             "datasource": "synchCollection"
    }

The datasource specifies the database and collection that will be used to store locking data. It should be possible to override default domain implementation:

   "myDomain" : {
              "class" : "com.redhat.MyDomainImplementation"
              "otherStuff" : "values"
    }

Backend: The domain implementation should provide the implementation for the synchronization primitives. The domain acts like a factory, and returns implementations for different sycnhronization primitives, for now only the mutex:

   SynchDomain {
        DBMutex getMutexImpl();
        ...
   }

and
   DBMutex {
       boolean acquire(...)
       boolean release(...)
        ...
   }    

If needed, this scheme can be extended later to support sequence number generation as well.

Core: LightblueFactory will have the factory interfaces for synchronization domains. This way execution bypasses the mediator/crud stack and leaves the implementation to the backend.

Rest: New rest APIs are needed to expose these APIs.
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
Clarification: this is a logical locking scheme. Locking a document
does not prevent access to the document, it only marks it as locked.
So all callers must use:

  if(acquire(myId,documentId)) {
    ..
     release(myId,documentId)
  }


On Wed, Jul 8, 2015 at 10:08 AM, bserdar [via lightblue-dev]
<[hidden email]> wrote:

> There appears to be a need to provide operations that guarantee atomicity
> and mutual exclusion at the core library level. The migrator uses a locking
> mechanism, esb mediator is planning to use that as well, and it would
> probably be useful going forward in implementing transaction support. This
> is a proposal that describes how we can add mutual exclusion operations at
> the core level.
>
> Data types:
>   - domain: The name of the backend and datastore that implements the
> synchronization mechanism. Available domains are configured and registered
> to the lightblue instance. For instance, a MongoDB implementation of
> synchronization primitives would specify the backend "mongo" with the name
> of the datasource to keep the synchronization data.
>   - callerId: A value that uniquely identifies the caller. This can be
> java.util.UUID.randomUUID()
>   - resourceId: A logical identifier of the resource. If the resource is a
> document in the database, this may be "entityName:uniqueId"
>
> Proposed APIs:
>
>    acquire(callerId,resourceId,domain [,ttl])
>
> Atomically acquire the resource for the caller. Fails if the resource is
> already acquired by another caller. Subsequent calls to acquire using the
> same callerId will require matching release calls. Optional ttl determines
> the timeout for the acquisition. If the mutex is acquired without any ping
> for ttl amount of time, the lock is released.
>
>
>    release(callerId, resourceId,domain)
>
> Releases the resource. If there are n calls to lock the same resource by the
> same caller, n calls to release by the same caller is required to release
> the resource.
>
>    isAcquired(callerId,resourceId,domain)
>
> Returns true if the resource is acquired by the caller.
>
>    ping(callerId, resourceId,domain)
>
> Update the mutex timestamp, so it would not expire.
>
> Implementation:
>
> Configuration subsystem: Need to add support for synchronization domain
> registration. Initially we will implement this for mongo subsystem only, and
> the synchronization domain should look like this:
>
>     "mongo" : {
>              "backend":"mongo",
>              "datasource": "synchCollection"
>     }
>
> The datasource specifies the database and collection that will be used to
> store locking data. It should be possible to override default domain
> implementation:
>
>    "myDomain" : {
>               "class" : "com.redhat.MyDomainImplementation"
>               "otherStuff" : "values"
>     }
>
> Backend: The domain implementation should provide the implementation for the
> synchronization primitives. The domain acts like a factory, and returns
> implementations for different sycnhronization primitives, for now only the
> mutex:
>
>    SynchDomain {
>         DBMutex getMutexImpl();
>         ...
>    }
>
> and
>    DBMutex {
>        boolean acquire(...)
>        boolean release(...)
>         ...
>    }
>
> If needed, this scheme can be extended later to support sequence number
> generation as well.
>
> Core: LightblueFactory will have the factory interfaces for synchronization
> domains. This way execution bypasses the mediator/crud stack and leaves the
> implementation to the backend.
>
> Rest: New rest APIs are needed to expose these APIs.
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

vritant
In reply to this post by bserdar
"If there are n calls to lock the same resource by the same caller"

Based on this I think you mean to imply that a caller could acquire multiple locks on the same resource.

are caller ids shared by individual threads of the same application ?

Is it correct to assume that a resource locked by a caller ( even once ) cannot be locked by another caller? or does each caller acquires a lock on a resource only for a particular caller id?

could you clarify whats the point of a caller id?

do we intend to have a background process to clear expired locks, or will every aquire request check for alive locks?

I recommend:

1. add an additional parameter resource type to all APIs ( that is, split "entityName:uniqueId" in to two params. this will let us set a limit on max number of locks per resource type )

2. add APIs:
   acquireAll(callerId,resourceType,resourceId,domain [,ttl])
   releaseAll(callerId,resourceType,resourceId,domain [,ttl])
   setMaxLocks( resourceType, max, domain)
   clearDeadLocks(domain[,resourceType,callerId]) ( if we do not automatically do this )
 
3. update the acquire / release APIs to specify how many locks are being requested / released

4. change isAcquired(callerId,resourceId,domain) to  getHowManyAcquired(callerId,resourceType,resourceId,domain)


NOTE: to meet current requirements, we could simply assume a resource can be locked only by one caller, only once 
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
The caller id identifies locking thread. The call:

   acquire(callerId,resourceId)

acquires the resource for that callerId. So:

   acquire("1","myResource")
   acquire("1", "myResource") -> success

But:

  acquire("1","myResource")
  acquire("2","myResource") -> fail


The point of callerId is to prevent the following:

 Thread1:
   acquire("myResource")
Thread2:
   release("myResource")

Without callerId, the above would work, and thread2 would be able to
unlock a resource held by thread1.


Re: expired locks: expired locks are no longer acquired. We can have a
weekly/monthly job to clear out expired locks.


Your recommendations:

1) Addding a "resource type" parameter: This is unnecessary. The
resource Id is a logical Id. It doesn't have to be of the form
"entityName:docId". Having a single logical resource identifier is the
most generic form of identifying a resource that supports one of more
components. With two arguments to the API, what happens when you have
only one, or more than two components to the resource ID?


2) What is the point of setMaxLocks()? What is the point of limiting
number of locks on an entity? What happens when that limit is
exceeded? And why?

3) Then it becomes a semaphore. Why is this necessary?

4) Why? The point of lock counting is simply to support nested locking
logic, and as a preparation for transactions.  There is no point in
knowing how many times you locked an object, if you structured your
code to match acquire/release pairs.




On Wed, Jul 8, 2015 at 6:10 PM, vritant [via lightblue-dev]
<[hidden email]> wrote:

> "If there are n calls to lock the same resource by the same caller"
>
> Based on this I think you mean to imply that a caller could acquire multiple
> locks on the same resource.
>
> are caller ids shared by individual threads of the same application ?
>
> Is it correct to assume that a resource locked by a caller ( even once )
> cannot be locked by another caller? or does each caller acquires a lock on a
> resource only for a particular caller id?
>
> could you clarify whats the point of a caller id?
>
> do we intend to have a background process to clear expired locks, or will
> every aquire request check for alive locks?
>
> I recommend:
>
> 1. add an additional parameter resource type to all APIs ( that is, split
> "entityName:uniqueId" in to two params. this will let us set a limit on max
> number of locks per resource type )
>
> 2. add APIs:
>    acquireAll(callerId,resourceType,resourceId,domain [,ttl])
>    releaseAll(callerId,resourceType,resourceId,domain [,ttl])
>    setMaxLocks( resourceType, max, domain)
>    clearDeadLocks(domain[,resourceType,callerId]) ( if we do not
> automatically do this )
>
> 3. update the acquire / release APIs to specify how many locks are being
> requested / released
>
> 4. change isAcquired(callerId,resourceId,domain) to
> getHowManyAcquired(callerId,resourceType,resourceId,domain)
>
>
> NOTE: to meet current requirements, we could simply assume a resource can be
> locked only by one caller, only once
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p374.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

dcrissman
> If there are n calls to lock the same resource by the same caller, n calls to release by the same caller is required to release the resource

Is there a use case for acquiring multiple locks to the same resource?
Should we be concerned about the case where the lock has not been released the correct amount of times?

On Wed, Jul 8, 2015 at 11:34 PM, bserdar [via lightblue-dev] <[hidden email]> wrote:
The caller id identifies locking thread. The call:

   acquire(callerId,resourceId)

acquires the resource for that callerId. So:

   acquire("1","myResource")
   acquire("1", "myResource") -> success

But:

  acquire("1","myResource")
  acquire("2","myResource") -> fail


The point of callerId is to prevent the following:

 Thread1:
   acquire("myResource")
Thread2:
   release("myResource")

Without callerId, the above would work, and thread2 would be able to
unlock a resource held by thread1.


Re: expired locks: expired locks are no longer acquired. We can have a
weekly/monthly job to clear out expired locks.


Your recommendations:

1) Addding a "resource type" parameter: This is unnecessary. The
resource Id is a logical Id. It doesn't have to be of the form
"entityName:docId". Having a single logical resource identifier is the
most generic form of identifying a resource that supports one of more
components. With two arguments to the API, what happens when you have
only one, or more than two components to the resource ID?


2) What is the point of setMaxLocks()? What is the point of limiting
number of locks on an entity? What happens when that limit is
exceeded? And why?

3) Then it becomes a semaphore. Why is this necessary?

4) Why? The point of lock counting is simply to support nested locking
logic, and as a preparation for transactions.  There is no point in
knowing how many times you locked an object, if you structured your
code to match acquire/release pairs.




On Wed, Jul 8, 2015 at 6:10 PM, vritant [via lightblue-dev]
<[hidden email]> wrote:

> "If there are n calls to lock the same resource by the same caller"
>
> Based on this I think you mean to imply that a caller could acquire multiple
> locks on the same resource.
>
> are caller ids shared by individual threads of the same application ?
>
> Is it correct to assume that a resource locked by a caller ( even once )
> cannot be locked by another caller? or does each caller acquires a lock on a
> resource only for a particular caller id?
>
> could you clarify whats the point of a caller id?
>
> do we intend to have a background process to clear expired locks, or will
> every aquire request check for alive locks?
>
> I recommend:
>
> 1. add an additional parameter resource type to all APIs ( that is, split
> "entityName:uniqueId" in to two params. this will let us set a limit on max
> number of locks per resource type )
>
> 2. add APIs:
>    acquireAll(callerId,resourceType,resourceId,domain [,ttl])
>    releaseAll(callerId,resourceType,resourceId,domain [,ttl])
>    setMaxLocks( resourceType, max, domain)
>    clearDeadLocks(domain[,resourceType,callerId]) ( if we do not
> automatically do this )
>
> 3. update the acquire / release APIs to specify how many locks are being
> requested / released
>
> 4. change isAcquired(callerId,resourceId,domain) to
> getHowManyAcquired(callerId,resourceType,resourceId,domain)
>
>
> NOTE: to meet current requirements, we could simply assume a resource can be
> locked only by one caller, only once
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p374.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML



If you reply to this email, your message will be added to the discussion below:
http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p375.html
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
The idea is to support nested calls where multiple layers acquires the resource:

void f1() {
   acquire(X)
   f2()
    release(X)
}

void f2() {
   acquire(X)
   do stuff
   release(X)
}

We could add a releaseAll(X) api to release all.

On Thu, Jul 9, 2015 at 6:48 AM, dcrissman [via lightblue-dev]
<[hidden email]> wrote:

>> If there are n calls to lock the same resource by the same caller, n calls
>> to release by the same caller is required to release the resource
>
> Is there a use case for acquiring multiple locks to the same resource?
> Should we be concerned about the case where the lock has not been released
> the correct amount of times?
>
> On Wed, Jul 8, 2015 at 11:34 PM, bserdar [via lightblue-dev] <[hidden
> email]> wrote:
>>
>> The caller id identifies locking thread. The call:
>>
>>    acquire(callerId,resourceId)
>>
>> acquires the resource for that callerId. So:
>>
>>    acquire("1","myResource")
>>    acquire("1", "myResource") -> success
>>
>> But:
>>
>>   acquire("1","myResource")
>>   acquire("2","myResource") -> fail
>>
>>
>> The point of callerId is to prevent the following:
>>
>>  Thread1:
>>    acquire("myResource")
>> Thread2:
>>    release("myResource")
>>
>> Without callerId, the above would work, and thread2 would be able to
>> unlock a resource held by thread1.
>>
>>
>> Re: expired locks: expired locks are no longer acquired. We can have a
>> weekly/monthly job to clear out expired locks.
>>
>>
>> Your recommendations:
>>
>> 1) Addding a "resource type" parameter: This is unnecessary. The
>> resource Id is a logical Id. It doesn't have to be of the form
>> "entityName:docId". Having a single logical resource identifier is the
>> most generic form of identifying a resource that supports one of more
>> components. With two arguments to the API, what happens when you have
>> only one, or more than two components to the resource ID?
>>
>>
>> 2) What is the point of setMaxLocks()? What is the point of limiting
>> number of locks on an entity? What happens when that limit is
>> exceeded? And why?
>>
>> 3) Then it becomes a semaphore. Why is this necessary?
>>
>> 4) Why? The point of lock counting is simply to support nested locking
>> logic, and as a preparation for transactions.  There is no point in
>> knowing how many times you locked an object, if you structured your
>> code to match acquire/release pairs.
>>
>>
>>
>>
>> On Wed, Jul 8, 2015 at 6:10 PM, vritant [via lightblue-dev]
>> <[hidden email]> wrote:
>>
>> > "If there are n calls to lock the same resource by the same caller"
>> >
>> > Based on this I think you mean to imply that a caller could acquire
>> > multiple
>> > locks on the same resource.
>> >
>> > are caller ids shared by individual threads of the same application ?
>> >
>> > Is it correct to assume that a resource locked by a caller ( even once )
>> > cannot be locked by another caller? or does each caller acquires a lock
>> > on a
>> > resource only for a particular caller id?
>> >
>> > could you clarify whats the point of a caller id?
>> >
>> > do we intend to have a background process to clear expired locks, or
>> > will
>> > every aquire request check for alive locks?
>> >
>> > I recommend:
>> >
>> > 1. add an additional parameter resource type to all APIs ( that is,
>> > split
>> > "entityName:uniqueId" in to two params. this will let us set a limit on
>> > max
>> > number of locks per resource type )
>> >
>> > 2. add APIs:
>> >    acquireAll(callerId,resourceType,resourceId,domain [,ttl])
>> >    releaseAll(callerId,resourceType,resourceId,domain [,ttl])
>> >    setMaxLocks( resourceType, max, domain)
>> >    clearDeadLocks(domain[,resourceType,callerId]) ( if we do not
>> > automatically do this )
>> >
>> > 3. update the acquire / release APIs to specify how many locks are being
>> > requested / released
>> >
>> > 4. change isAcquired(callerId,resourceId,domain) to
>> > getHowManyAcquired(callerId,resourceType,resourceId,domain)
>> >
>> >
>> > NOTE: to meet current requirements, we could simply assume a resource
>> > can be
>> > locked only by one caller, only once
>> >
>> > ________________________________
>> > If you reply to this email, your message will be added to the discussion
>> > below:
>> >
>> > http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p374.html
>> > To start a new topic under lightblue-dev, email
>> > [hidden email]
>> > To unsubscribe from lightblue-dev, click here.
>> > NAML
>>
>>
>> ________________________________
>> If you reply to this email, your message will be added to the discussion
>> below:
>>
>> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p375.html
>> To start a new topic under lightblue-dev, email [hidden email]
>> To unsubscribe from lightblue-dev, click here.
>> NAML
>
>
>
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p376.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

vritant
In reply to this post by bserdar
thanks for the explanation bserdar.
if caller ids are thread ids, and other threads cant lock a resource while another threads holds the lock, these APIs work for me.
via these APIs we are assuming that if there exist callers that want to ensure a resource can be locked only once by themselves, they should be aware if they already hold a lock , and not try to lock it again, a fair assumption to make. a releaseAll API would be nice though.
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
Caller ID can be thread ID if you're running in a single node. If
there are multiple nodes running, use UUID.

On Thu, Jul 9, 2015 at 9:27 AM, vritant [via lightblue-dev]
<[hidden email]> wrote:

> thanks for the explanation bserdar.
> if caller ids are thread ids, and other threads cant lock a resource while
> another threads holds the lock, these APIs work for me.
> via these APIs we are assuming that if there exist callers that want to
> ensure a resource can be locked only once by themselves, they should be
> aware if they already hold a lock , and not try to lock it again, a fair
> assumption to make. a releaseAll API would be nice though.
>
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p378.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

jewzaam
Administrator

How about requiring ttl?
As for reaping expired locks, if we are storing in mongo just create a ttl index.
I agree, no value in returning count of locks acquired. I don't think we should have a release all app though. This allows for sloppy client code.


On Thu, Jul 9, 2015, 11:40 AM bserdar [via lightblue-dev] <[hidden email]> wrote:
Caller ID can be thread ID if you're running in a single node. If
there are multiple nodes running, use UUID.

On Thu, Jul 9, 2015 at 9:27 AM, vritant [via lightblue-dev]
<[hidden email]> wrote:

> thanks for the explanation bserdar.
> if caller ids are thread ids, and other threads cant lock a resource while
> another threads holds the lock, these APIs work for me.
> via these APIs we are assuming that if there exist callers that want to
> ensure a resource can be locked only once by themselves, they should be
> aware if they already hold a lock , and not try to lock it again, a fair
> assumption to make. a releaseAll API would be nice though.
>
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p378.html
> To start a new topic under lightblue-dev, email
> To unsubscribe from lightblue-dev, click here.
> NAML
If you reply to this email, your message will be added to the discussion below:
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
I am changing my mind about counting calls to acquire(). There is an
isAcquired() API, so nested locking can be replaced by:

if(!isAcquired())
    acquire()
 ...

calls. We are not going to use this for thread synchronization, so
this should not cause race conditions.

+1 for ttl index

On Fri, Jul 10, 2015 at 6:07 AM, jewzaam [via lightblue-dev]
<[hidden email]> wrote:

> How about requiring ttl?
> As for reaping expired locks, if we are storing in mongo just create a ttl
> index.
> I agree, no value in returning count of locks acquired. I don't think we
> should have a release all app though. This allows for sloppy client code.
>
>
> On Thu, Jul 9, 2015, 11:40 AM bserdar [via lightblue-dev] <[hidden email]>
> wrote:
>>
>> Caller ID can be thread ID if you're running in a single node. If
>> there are multiple nodes running, use UUID.
>>
>> On Thu, Jul 9, 2015 at 9:27 AM, vritant [via lightblue-dev]
>> <[hidden email]> wrote:
>>
>> > thanks for the explanation bserdar.
>> > if caller ids are thread ids, and other threads cant lock a resource
>> > while
>> > another threads holds the lock, these APIs work for me.
>> > via these APIs we are assuming that if there exist callers that want to
>> > ensure a resource can be locked only once by themselves, they should be
>> > aware if they already hold a lock , and not try to lock it again, a fair
>> > assumption to make. a releaseAll API would be nice though.
>> >
>> >
>> > ________________________________
>> > If you reply to this email, your message will be added to the discussion
>> > below:
>> >
>> > http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p378.html
>> > To start a new topic under lightblue-dev, email
>> > [hidden email]
>> > To unsubscribe from lightblue-dev, click here.
>> > NAML
>> If you reply to this email, your message will be added to the discussion
>> below:
>>
>> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p379.html
>> To start a new topic under lightblue-dev, email [hidden email]
>> To unsubscribe from lightblue-dev, click here.
>> NAML
>
>
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p380.html
> To start a new topic under lightblue-dev, email
> [hidden email]
> To unsubscribe from lightblue-dev, click here.
> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

bserdar
In reply to this post by jewzaam
Here's the final proposal for locking api:

    acquire(callerId,resourceId,domain [,ttl])

Semantics similar to reentrant lock. ttl is optional, but there will
be an implementation specified maximum timeout for all locks.

   release(callerId, resourceId,domain)

Releases the resource. If there are n calls to lock the same resource
by the same caller, n calls to release by the same caller is required
to release the resource.

   getLockCount(callerId,resourceId,domain)

Replacement for releaseAll and isAcquired, returns the number of times
resource is locked.

   ping(callerId, resourceId,domain)

Ping the lock so it won't expire.


On Fri, Jul 10, 2015 at 7:31 AM, Burak Serdar <[hidden email]> wrote:

> I am changing my mind about counting calls to acquire(). There is an
> isAcquired() API, so nested locking can be replaced by:
>
> if(!isAcquired())
>     acquire()
>  ...
>
> calls. We are not going to use this for thread synchronization, so
> this should not cause race conditions.
>
> +1 for ttl index
>
> On Fri, Jul 10, 2015 at 6:07 AM, jewzaam [via lightblue-dev]
> <[hidden email]> wrote:
>> How about requiring ttl?
>> As for reaping expired locks, if we are storing in mongo just create a ttl
>> index.
>> I agree, no value in returning count of locks acquired. I don't think we
>> should have a release all app though. This allows for sloppy client code.
>>
>>
>> On Thu, Jul 9, 2015, 11:40 AM bserdar [via lightblue-dev] <[hidden email]>
>> wrote:
>>>
>>> Caller ID can be thread ID if you're running in a single node. If
>>> there are multiple nodes running, use UUID.
>>>
>>> On Thu, Jul 9, 2015 at 9:27 AM, vritant [via lightblue-dev]
>>> <[hidden email]> wrote:
>>>
>>> > thanks for the explanation bserdar.
>>> > if caller ids are thread ids, and other threads cant lock a resource
>>> > while
>>> > another threads holds the lock, these APIs work for me.
>>> > via these APIs we are assuming that if there exist callers that want to
>>> > ensure a resource can be locked only once by themselves, they should be
>>> > aware if they already hold a lock , and not try to lock it again, a fair
>>> > assumption to make. a releaseAll API would be nice though.
>>> >
>>> >
>>> > ________________________________
>>> > If you reply to this email, your message will be added to the discussion
>>> > below:
>>> >
>>> > http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p378.html
>>> > To start a new topic under lightblue-dev, email
>>> > [hidden email]
>>> > To unsubscribe from lightblue-dev, click here.
>>> > NAML
>>> If you reply to this email, your message will be added to the discussion
>>> below:
>>>
>>> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p379.html
>>> To start a new topic under lightblue-dev, email [hidden email]
>>> To unsubscribe from lightblue-dev, click here.
>>> NAML
>>
>>
>>
>> ________________________________
>> If you reply to this email, your message will be added to the discussion
>> below:
>> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p380.html
>> To start a new topic under lightblue-dev, email
>> [hidden email]
>> To unsubscribe from lightblue-dev, click here.
>> NAML
Reply | Threaded
Open this post in threaded view
|

Re: RFC: Lightblue synchronization primitives

jewzaam
Administrator

+1


On Fri, Jul 10, 2015, 10:03 AM bserdar [via lightblue-dev] <[hidden email]> wrote:
Here's the final proposal for locking api:

    acquire(callerId,resourceId,domain [,ttl])

Semantics similar to reentrant lock. ttl is optional, but there will
be an implementation specified maximum timeout for all locks.

   release(callerId, resourceId,domain)

Releases the resource. If there are n calls to lock the same resource
by the same caller, n calls to release by the same caller is required
to release the resource.

   getLockCount(callerId,resourceId,domain)

Replacement for releaseAll and isAcquired, returns the number of times
resource is locked.

   ping(callerId, resourceId,domain)

Ping the lock so it won't expire.


On Fri, Jul 10, 2015 at 7:31 AM, Burak Serdar <[hidden email]> wrote:

> I am changing my mind about counting calls to acquire(). There is an
> isAcquired() API, so nested locking can be replaced by:
>
> if(!isAcquired())
>     acquire()
>  ...
>
> calls. We are not going to use this for thread synchronization, so
> this should not cause race conditions.
>
> +1 for ttl index
>
> On Fri, Jul 10, 2015 at 6:07 AM, jewzaam [via lightblue-dev]
> <[hidden email]> wrote:
>> How about requiring ttl?
>> As for reaping expired locks, if we are storing in mongo just create a ttl
>> index.
>> I agree, no value in returning count of locks acquired. I don't think we
>> should have a release all app though. This allows for sloppy client code.
>>
>>
>> On Thu, Jul 9, 2015, 11:40 AM bserdar [via lightblue-dev] <[hidden email]>
>> wrote:

>>>
>>> Caller ID can be thread ID if you're running in a single node. If
>>> there are multiple nodes running, use UUID.
>>>
>>> On Thu, Jul 9, 2015 at 9:27 AM, vritant [via lightblue-dev]
>>> <[hidden email]> wrote:
>>>
>>> > thanks for the explanation bserdar.
>>> > if caller ids are thread ids, and other threads cant lock a resource
>>> > while
>>> > another threads holds the lock, these APIs work for me.
>>> > via these APIs we are assuming that if there exist callers that want to
>>> > ensure a resource can be locked only once by themselves, they should be
>>> > aware if they already hold a lock , and not try to lock it again, a fair
>>> > assumption to make. a releaseAll API would be nice though.
>>> >
>>> >
>>> > ________________________________
>>> > If you reply to this email, your message will be added to the discussion
>>> > below:
>>> >
>>> > http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p378.html
>>> > To start a new topic under lightblue-dev, email
>>> > [hidden email]
>>> > To unsubscribe from lightblue-dev, click here.
>>> > NAML
>>> If you reply to this email, your message will be added to the discussion
>>> below:
>>>
>>> http://dev.forum.lightblue.io/RFC-Lightblue-synchronization-primitives-tp372p379.html
>>> To start a new topic under lightblue-dev, email [hidden email]
>>> To unsubscribe from lightblue-dev, click here.
>>> NAML
>>
>>
>>
>> ________________________________
>> If you reply to this email, your message will be added to the discussion
>> below:

>> To start a new topic under lightblue-dev, email
>> [hidden email]
>> To unsubscribe from lightblue-dev, click here.
>> NAML
If you reply to this email, your message will be added to the discussion below:
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML