[Seaside] [Glass] Why session locking is necessary for Seaside?
dale.henrichs at gemtalksystems.com
Tue Mar 21 23:32:10 UTC 2017
On 03/21/2017 02:13 PM, Mariano Martinez Peck wrote:
> On Tue, Mar 21, 2017 at 5:57 PM, Dale Henrichs via Glass
> <glass at lists.gemtalksystems.com
> <mailto:glass at lists.gemtalksystems.com>> wrote:
> On 03/21/2017 12:25 PM, Mariano Martinez Peck via Glass wrote:
>> I was reading this old post from Dale  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 ofWATally, 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
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  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
> 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:)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the seaside