Session-based locking?

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

Session-based locking?

Millies, Sebastian

Hello there,

 

is there anything in java.util.concurrent that supports locking based on sessions instead of threads?

 

Here’s what I have in mind: A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server. Which thread services which request basically being determined by chance. Finally, the client hits “save”, leaves edit mode and is finished.

 

The server requests must be processed in a cooperative way: Some require exclusive locks on specific resources, some require only read locks, some require both. I cannot use ReentrantReadWriteLock, because a) that does not permit me to unlock from a different thread, and b) the re-entrancy itself should also rather be based on the session id (a String) than on the thread.

 

In my case, the problem is simplified by the fact that upgrading a lock from read to write is never needed. Also, the server immediately knows for each request what locks to acquire, and if it can’t get them, there is no point in letting the client wait, the server can fail immediately, rollback any intermediate changes, and tell the client. (Something like try-lock with a minimal timeout would do the trick.) It follows that there is never any problem of finding and interrupting waiting any threads waiting on a lock.

 

I have googled a bit. The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”. Or build directly on LockSupport. Both sound daunting. Does anyone perhaps know of a library that would offer support on a somewhat higher level ? Perhaps something that could be taken out of a web application framework? I imagine the problem must be common.

 

Best Regards,

Sebastian


Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Peter Levart

Hi Millies,


On 06/20/2016 04:46 PM, Millies, Sebastian wrote:

Hello there,

 

is there anything in java.util.concurrent that supports locking based on sessions instead of threads?

 

Here’s what I have in mind: A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server. Which thread services which request basically being determined by chance. Finally, the client hits “save”, leaves edit mode and is finished.


...can client initiate concurrent requests in the same "session" ? A browser client can (for example when loading images in the html page) or when hitting reload button while server is still serving previous request. How would you want to treat such concurrent requests initiated from the same client "session" ?

Regards, Peter

 

The server requests must be processed in a cooperative way: Some require exclusive locks on specific resources, some require only read locks, some require both. I cannot use ReentrantReadWriteLock, because a) that does not permit me to unlock from a different thread, and b) the re-entrancy itself should also rather be based on the session id (a String) than on the thread.

 

In my case, the problem is simplified by the fact that upgrading a lock from read to write is never needed. Also, the server immediately knows for each request what locks to acquire, and if it can’t get them, there is no point in letting the client wait, the server can fail immediately, rollback any intermediate changes, and tell the client. (Something like try-lock with a minimal timeout would do the trick.) It follows that there is never any problem of finding and interrupting waiting any threads waiting on a lock.

 

I have googled a bit. The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”. Or build directly on LockSupport. Both sound daunting. Does anyone perhaps know of a library that would offer support on a somewhat higher level ? Perhaps something that could be taken out of a web application framework? I imagine the problem must be common.

 

Best Regards,

Sebastian


Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Jens Wilke
In reply to this post by Millies, Sebastian
Millies,

On Monday 20 June 2016 14:46:00 Millies, Sebastian wrote:
> Does anyone perhaps know of a library that would offer support on a somewhat higher level ?

From what you describe it seems to be not a "session" but a "transaction":

> A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server.

At the higher level, there are (distributed) transaction managers.

> The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”.

What resources you need to protect with a lock? You need a lock per resource, not per client session / transaction.

Why you need counting, when actually the client determines the start and end?

Cheers,

Jens

--
"Everything superfluous is wrong!"

   // Jens Wilke - headissue GmbH - Germany
 \//  https://headissue.com
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Nathan and Ila Reynolds
In reply to this post by Millies, Sebastian

I don’t know how well this works.  I didn’t test it.  At least it compiles.  I release it to the public domain.  Use it at your own risk.

 

This code will ensure that the resource it protects is only used by a single session.  It does not ensure that multiple thread for the same session don’t access the resource concurrently.  For that, a simple synchronized block may suffice.

 

This code only handles a single writer case.  It doesn’t handle multiple readers.

 

import java.time.Duration;

import java.time.Instant;

 

public class SessionLock

{

   private String m_session;   // The session which owns the lock

   private int    m_count;

 

   public boolean tryLock(String session, Duration time)

   {

      Instant deadline;

      long sleep;

 

      if (session == null)

         throw new NullPointerException("session is null");

 

      deadline = Instant.

         now().

         plus(time);

 

      synchronized (this)

      {

         while (true)

         {

            if (m_session == null)

            {

               m_session = session;

               m_count   = 1;

 

               return(true);

            }

 

            if (m_session.equals(session))

            {

               m_count++;

               return(true);

            }

 

            sleep = Duration.

               between(Instant.now(), deadline).

               toMillis();

 

            if (sleep <= 0)

               return(false);

 

            try

            {

               wait(sleep);

            }

            catch (InterruptedException e)

            {

               deadline = Instant.EPOCH;    // Wake up and try to acquire the lock.  If fails, then exit immediately.

            }

         }

      }

   }

 

   public void unlock(String session)

   {

      synchronized (this)

      {

         if (m_session == null)

            throw new IllegalStateException("The lock is not acquired");

 

         if (!m_session.equals(session))

            throw new IllegalStateException("The lock is not owned by " + session + ".  It is owned by " + m_session);

 

         if (m_count <= 0)

            throw new IllegalStateException("The lock count is unexpected " + m_count);

 

         if (--m_count > 0)

            return;

 

         m_session = null;

 

         notify();

      }

   }

}

 

-Nathan

 

From: Concurrency-interest [mailto:[hidden email]] On Behalf Of Millies, Sebastian
Sent: Monday, June 20, 2016 7:46 AM
To: [hidden email]
Subject: [concurrency-interest] Session-based locking?

 

Hello there,

 

is there anything in java.util.concurrent that supports locking based on sessions instead of threads?

 

Here’s what I have in mind: A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server. Which thread services which request basically being determined by chance. Finally, the client hits “save”, leaves edit mode and is finished.

 

The server requests must be processed in a cooperative way: Some require exclusive locks on specific resources, some require only read locks, some require both. I cannot use ReentrantReadWriteLock, because a) that does not permit me to unlock from a different thread, and b) the re-entrancy itself should also rather be based on the session id (a String) than on the thread.

 

In my case, the problem is simplified by the fact that upgrading a lock from read to write is never needed. Also, the server immediately knows for each request what locks to acquire, and if it can’t get them, there is no point in letting the client wait, the server can fail immediately, rollback any intermediate changes, and tell the client. (Something like try-lock with a minimal timeout would do the trick.) It follows that there is never any problem of finding and interrupting waiting any threads waiting on a lock.

 

I have googled a bit. The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”. Or build directly on LockSupport. Both sound daunting. Does anyone perhaps know of a library that would offer support on a somewhat higher level ? Perhaps something that could be taken out of a web application framework? I imagine the problem must be common.

 

Best Regards,

Sebastian

 

Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Millies, Sebastian
In reply to this post by Jens Wilke
thanks for the feed-back (and the code). I'll try to answer your questions all in one post.

@Jens: yes, it's similar to a transaction, except the resources I have to protect are not transactional: some are singleton objects in memory, some are files, one is actually a database. They don't support XA, of course, and introducing a full-fledged tx manager seems overkill. In fact, there is already a notion of exclusive locking in place, which needs to be relaxed by introducing read-write-locking. (@Reynoldses: in fact a key requirement).

 I thought of counting, because any number of sessions can acquire a read lock to the same resource, so perhaps having one AtomicInteger per resource with values -1 (write-locked), 0 (free) , or x > 0 (read-locked by x sessions) would already do the job. I wouldn't even need a notion of ownership if I don't offer upgrade, re-entrancy would be automatic, although there would be no lock-upgrade/downgrade functionality.

@Peter: It's not a browser client, I believe it's a swing client that communicates with the backend over a combination of SOAP and protobuf technology. Don't ask me more details, I don't know them. But they don't do concurrent requests within the same session.

-- Sebastian

-----Original Message-----
From: Jens Wilke [mailto:[hidden email]]
Sent: Monday, June 20, 2016 5:31 PM
To: [hidden email]
Cc: Millies, Sebastian
Subject: Re: [concurrency-interest] Session-based locking?

Millies,

On Monday 20 June 2016 14:46:00 Millies, Sebastian wrote:
> Does anyone perhaps know of a library that would offer support on a somewhat higher level ?

From what you describe it seems to be not a "session" but a "transaction":

> A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server.

At the higher level, there are (distributed) transaction managers.

> The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”.

What resources you need to protect with a lock? You need a lock per resource, not per client session / transaction.

Why you need counting, when actually the client determines the start and end?

Cheers,

Jens

-----Original Message----

From: Peter Levart [mailto:[hidden email]]
Sent: Monday, June 20, 2016 5:24 PM
To: Millies, Sebastian; [hidden email]
Subject: Re: [concurrency-interest] Session-based locking?

Hi Millies,

...can client initiate concurrent requests in the same "session" ? A browser client can (for example when loading images in the html page) or when hitting reload button while server is still serving previous request. How would you want to treat such concurrent requests initiated from the same client "session" ?

Regards, Peter



Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Alex Otenko

On 21 Jun 2016, at 08:59, Millies, Sebastian <[hidden email]> wrote:

thanks for the feed-back (and the code). I'll try to answer your questions all in one post.

@Jens: yes, it's similar to a transaction, except the resources I have to protect are not transactional: some are singleton objects in memory, some are files, one is actually a database. They don't support XA, of course, and introducing a full-fledged tx manager seems overkill. In fact, there is already a notion of exclusive locking in place, which needs to be relaxed by introducing read-write-locking. (@Reynoldses: in fact a key requirement).

I thought of counting, because any number of sessions can acquire a read lock to the same resource, so perhaps having one AtomicInteger per resource with values -1 (write-locked), 0 (free) , or x > 0 (read-locked by x sessions) would already do the job. I wouldn't even need a notion of ownership if I don't offer upgrade, re-entrancy would be automatic, although there would be no lock-upgrade/downgrade functionality.

@Peter: It's not a browser client, I believe it's a swing client that communicates with the backend over a combination of SOAP and protobuf technology. Don't ask me more details, I don't know them. But they don't do concurrent requests within the same session.

But are they known to terminate?

Eg something not releasing a lock would become a big deal. This is less of an issue in a local lock, as the communications are far more reliable.


Alex



-- Sebastian

-----Original Message-----
From: Jens Wilke [[hidden email]]
Sent: Monday, June 20, 2016 5:31 PM
To: [hidden email]
Cc: Millies, Sebastian
Subject: Re: [concurrency-interest] Session-based locking?

Millies,

On Monday 20 June 2016 14:46:00 Millies, Sebastian wrote:
Does anyone perhaps know of a library that would offer support on a somewhat higher level ?

From what you describe it seems to be not a "session" but a "transaction":

A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server.

At the higher level, there are (distributed) transaction managers.

The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”.

What resources you need to protect with a lock? You need a lock per resource, not per client session / transaction.

Why you need counting, when actually the client determines the start and end?

Cheers,

Jens

-----Original Message----

From: Peter Levart [[hidden email]]
Sent: Monday, June 20, 2016 5:24 PM
To: Millies, Sebastian; [hidden email]
Subject: Re: [concurrency-interest] Session-based locking?

Hi Millies,

...can client initiate concurrent requests in the same "session" ? A browser client can (for example when loading images in the html page) or when hitting reload button while server is still serving previous request. How would you want to treat such concurrent requests initiated from the same client "session" ?

Regards, Peter



Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Session-based locking?

Peter Levart



On 06/22/2016 08:53 AM, Alex Otenko wrote:

On 21 Jun 2016, at 08:59, Millies, Sebastian <[hidden email]> wrote:

thanks for the feed-back (and the code). I'll try to answer your questions all in one post.

@Jens: yes, it's similar to a transaction, except the resources I have to protect are not transactional: some are singleton objects in memory, some are files, one is actually a database. They don't support XA, of course, and introducing a full-fledged tx manager seems overkill. In fact, there is already a notion of exclusive locking in place, which needs to be relaxed by introducing read-write-locking. (@Reynoldses: in fact a key requirement).

I thought of counting, because any number of sessions can acquire a read lock to the same resource, so perhaps having one AtomicInteger per resource with values -1 (write-locked), 0 (free) , or x > 0 (read-locked by x sessions) would already do the job. I wouldn't even need a notion of ownership if I don't offer upgrade, re-entrancy would be automatic, although there would be no lock-upgrade/downgrade functionality.

@Peter: It's not a browser client, I believe it's a swing client that communicates with the backend over a combination of SOAP and protobuf technology. Don't ask me more details, I don't know them. But they don't do concurrent requests within the same session.

But are they known to terminate?

Eg something not releasing a lock would become a big deal. This is less of an issue in a local lock, as the communications are far more reliable.


Alex

Then some kind of session-expiry server-side mechanism would have to be used to release the locks held by expired session(s). But those would be just locks - what about state that was changed as part of holding those locks which may be left inconsistent?

I played with the locking aspect only. Here's a simple ReentrantSessionRWLock with API similar to ReentrantReadWriteLock, supporting session expiry:

    http://cr.openjdk.java.net/~plevart/misc/ReentrantSessionRWLock/

Regards, Peter




-- Sebastian

-----Original Message-----
From: Jens Wilke [[hidden email]]
Sent: Monday, June 20, 2016 5:31 PM
To: [hidden email]
Cc: Millies, Sebastian
Subject: Re: [concurrency-interest] Session-based locking?

Millies,

On Monday 20 June 2016 14:46:00 Millies, Sebastian wrote:
Does anyone perhaps know of a library that would offer support on a somewhat higher level ?

From what you describe it seems to be not a "session" but a "transaction":

A client-server architecture in which the client initiates a logical unit of work (“LUW”, an SAP term), i. e. basically enters edit mode. The client then proceeds to make any number of server requests, which will get serviced by different threads on the server.

At the higher level, there are (distributed) transaction managers.

The most common recommendation seems to be to roll my own Lock implementation internally using Semaphore to implement a “counting lock”.

What resources you need to protect with a lock? You need a lock per resource, not per client session / transaction.

Why you need counting, when actually the client determines the start and end?

Cheers,

Jens

-----Original Message----

From: Peter Levart [[hidden email]]
Sent: Monday, June 20, 2016 5:24 PM
To: Millies, Sebastian; [hidden email]
Subject: Re: [concurrency-interest] Session-based locking?

Hi Millies,

...can client initiate concurrent requests in the same "session" ? A browser client can (for example when loading images in the html page) or when hitting reload button while server is still serving previous request. How would you want to treat such concurrent requests initiated from the same client "session" ?

Regards, Peter



Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB 1562 - Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman), Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt; - Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas Bereczky - http://www.softwareag.com

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest