Re: [Glass] Why session locking is necessary for Seaside?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] Why session locking is necessary for Seaside?

Mariano Martinez Peck

On Tue, Mar 21, 2017 at 5:57 PM, Dale Henrichs via Glass <[hidden email]> wrote:



On 03/21/2017 12:25 PM, Mariano Martinez Peck via Glass wrote:
Hi,

I was reading this old post from Dale [1] which explains the topic very nice. After having watched the #seasideProcessRequestWithRetry:resultBlock:  and WASession >> handle:   and the post, I have some questions. 

On one paragraph you said:

"Object locking as a technique for avoiding commit conflicts shares the ‘retry on failure’ model of WATally, so it isn’t necessarily superior to ‘retry on commit failure’. It is a superior technique, if you need to protect logical updates where a physical conflict cannot be guaranteed (i.e., updates to different portions of an object graph).
"

And that's EXACTLY what I was wondering... why the commit failure (conflicts) / abort / retry would NOT be enough for sessions and avoid the lock?  Is that because of that sentence " if you need to protect logical updates where a physical conflict cannot be guaranteed"  
So that's the case for Seaside sessions? It's not safe to update (without conflict) different parts of the session subgraph ?
The primary reason for the Seaside session object lock is that Seaside itself had (and presumably still has) a mutex on the session object that only allows Pharo-based Seaside to handle one request at a time in a single vm. 


I wonder if that's still the case on latest Seaside. Do you have a clue where I can check myself?

 
The session object lock emulates the in-vm mutex semantics for multi-gem GemStone and guarantees logical consistency for the session state.

I am intrigued about the ORIGINAL needs of such a need. Because as Pharo and GemStone and too it makes me wonder if the lock would be needed on GemStone.

 
Unfortunately it is not enough to rely conflicts to guarantee logical consistency.

Do you have more details about this? An example maybe? 

 


This is sad, because many many many requests would be read-only to what the session matters (unless there is something obvious I am not seeing?) and in that case, the requests WOULD be able to be parallelized on different Gems.  

On the other hand, if you know that you have read-only requests, you could arrange for a pool of seaside gems to be serving read-only requests by putting the gems behind a different ip address, disabling the session lock altogether and unconditionally aborting after finishing request processing (this is roughly the equivalent of what Johan is doing with his pool of REST gems -- I think). I suppose you could embed something in the http request itself to tell the server to process a read only request as well... that way your entire pool of seaside gems could alternate between server session-based requests and session-less requests ...


I just analyzed this carefully, and I cannot guarantee my requests are fully read only ahahahahhaha. 
 
I know Johan recommends session affinity [2] and I understand why. It's just that I would prefer to be able to have multiple requests to the same session in parallel in different gems. At least those that wouldn't fail due to a commit conflict on the session. 

This does bring up a question that I haven't thought about before:

  How does an Ajax request "bypass" the session mutex in a Pharo-based Seaside vm?


Does it?


 
Dale

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass




--

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] Why session locking is necessary for Seaside?

Dale Henrichs-3



On 03/21/2017 02:13 PM, Mariano Martinez Peck wrote:

On Tue, Mar 21, 2017 at 5:57 PM, Dale Henrichs via Glass <[hidden email]> wrote:



On 03/21/2017 12:25 PM, Mariano Martinez Peck via Glass wrote:
Hi,

I was reading this old post from Dale [1] which explains the topic very nice. After having watched the #seasideProcessRequestWithRetry:resultBlock:  and WASession >> handle:   and the post, I have some questions. 

On one paragraph you said:

"Object locking as a technique for avoiding commit conflicts shares the ‘retry on failure’ model of WATally, so it isn’t necessarily superior to ‘retry on commit failure’. It is a superior technique, if you need to protect logical updates where a physical conflict cannot be guaranteed (i.e., updates to different portions of an object graph).
"

And that's EXACTLY what I was wondering... why the commit failure (conflicts) / abort / retry would NOT be enough for sessions and avoid the lock?  Is that because of that sentence " if you need to protect logical updates where a physical conflict cannot be guaranteed"  
So that's the case for Seaside sessions? It's not safe to update (without conflict) different parts of the session subgraph ?
The primary reason for the Seaside session object lock is that Seaside itself had (and presumably still has) a mutex on the session object that only allows Pharo-based Seaside to handle one request at a time in a single vm. 


I wonder if that's still the case on latest Seaside. Do you have a clue where I can check myself?

 
The session object lock emulates the in-vm mutex semantics for multi-gem GemStone and guarantees logical consistency for the session state.

I am intrigued about the ORIGINAL needs of such a need. Because as Pharo and GemStone and too it makes me wonder if the lock would be needed on GemStone.
I've read some of the newer Seaside code and while I can easily tell that there is still session state being copied and restored (see senders and implementers of snapShotCopy and restoreFromSnapShot:), it is not easy to tell how it is being protected from logical or physical corruption ... WACache has a mutex protecting the cache updates, but I still don't see how the component snapshots are being protected from concurrent updates ...

Unfortunately it is not enough to rely conflicts to guarantee logical consistency.

Do you have more details about this? An example maybe?

Logical inconsistency occurs in transactions when you use stale data to make a calculation or produce a report or update persistent state. For a simple example, let's say that you look at a persistent count and you use that count to generate a report. The report will be logically consistent if the persistent count and the data used to generate the report are guaranteed to be in the same transactional view. If you read the persistent count, abort and then generate the report, you will have a logical inconsistency if the count changed between the time that you read the count and generated your report and there will be no commit conflict to indicate that there is an inconsistency, because you are reading inconsistent data. 

A persistent logical inconsistency can occur if you update an object based upon the stale counter value and then commit ... There is no guaranteed commit conflict in this case and no indication that you've introduced corruption.

if you use an object lock to protect the counter and the data used to generate the report, then you can know that your data is consistent by acquiring the object lock, read the counter abort, generate your report and release the lock ...

 


This is sad, because many many many requests would be read-only to what the session matters (unless there is something obvious I am not seeing?) and in that case, the requests WOULD be able to be parallelized on different Gems.  

On the other hand, if you know that you have read-only requests, you could arrange for a pool of seaside gems to be serving read-only requests by putting the gems behind a different ip address, disabling the session lock altogether and unconditionally aborting after finishing request processing (this is roughly the equivalent of what Johan is doing with his pool of REST gems -- I think). I suppose you could embed something in the http request itself to tell the server to process a read only request as well... that way your entire pool of seaside gems could alternate between server session-based requests and session-less requests ...


I just analyzed this carefully, and I cannot guarantee my requests are fully read only ahahahahhaha.
It's not only the Seaside session state that is being protected from concurrent updates by the Seaside session lock. Your application data is also being protected and you don't have to carefully analyze your code to know whether it is safe or not ...

I would say that it is theoretically possible to move the transaction boundaries further down into the Seaside code, but I'm not so sure that it can be done without radically changing how Seaside works ...

It occurs to me that you could still use a pool of REST gems that do not lock session state as long as you put your own protections in place ... perhaps objects locks at a finer level of granularity?
 
I know Johan recommends session affinity [2] and I understand why. It's just that I would prefer to be able to have multiple requests to the same session in parallel in different gems. At least those that wouldn't fail due to a commit conflict on the session. 

This does bring up a question that I haven't thought about before:

  How does an Ajax request "bypass" the session mutex in a Pharo-based Seaside vm?


Does it?
If I knew, I wouldn't ask the question:)

Dale

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] Why session locking is necessary for Seaside?

Johan Brichau-2

>> I am intrigued about the ORIGINAL needs of such a need. Because as Pharo and GemStone and too it makes me wonder if the lock would be needed on GemStone.
> I've read some of the newer Seaside code and while I can easily tell that there is still session state being copied and restored (see senders and implementers of snapShotCopy and restoreFromSnapShot:), it is not easy to tell how it is being protected from logical or physical corruption ... WACache has a mutex protecting the cache updates, but I still don't see how the component snapshots are being protected from concurrent updates ...

That should be the WAMutualExclusionFilter, no?
This one is never installed in the Gemstone code.

cheers
Johan
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] Why session locking is necessary for Seaside?

Dale Henrichs-3


On 03/22/2017 02:42 AM, Johan Brichau wrote:
>>> I am intrigued about the ORIGINAL needs of such a need. Because as Pharo and GemStone and too it makes me wonder if the lock would be needed on GemStone.
>> I've read some of the newer Seaside code and while I can easily tell that there is still session state being copied and restored (see senders and implementers of snapShotCopy and restoreFromSnapShot:), it is not easy to tell how it is being protected from logical or physical corruption ... WACache has a mutex protecting the cache updates, but I still don't see how the component snapshots are being protected from concurrent updates ...
> That should be the WAMutualExclusionFilter, no?
> This one is never installed in the Gemstone code.
>
Ah, that does look like the one ... so maybe you know how/if this filter
is bypassed by ajax calls when running in Pharo ... or perhaps it's just
more visible with GemStone?

Dale
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] Why session locking is necessary for Seaside?

Johan Brichau-2

On 22 Mar 2017, at 18:50, Dale Henrichs <[hidden email]> wrote:

That should be the WAMutualExclusionFilter, no?
This one is never installed in the Gemstone code.

Ah, that does look like the one ... so maybe you know how/if this filter is bypassed by ajax calls when running in Pharo ... or perhaps it's just more visible with GemStone?

It’s installed as a filter on the session. Everytime the session is accessed, the request passes by that mutual exclusion filter.
So: ajax requests are also mutually exclusive in Pharo.

They should be, since ajax requests update the component state as well.

Instead of adding read-only callbacks to Seaside, I’m more in favor of taking a look to make it easier to redirect callbacks to a REST service (Seaside or Zinc) where there is no session to lock by definition.
That’s what we do if needed, but it’s true that it’s all hand-made.

Johan

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside