[
https://issues.apache.org/jira/browse/TAP5-2799?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17900258#comment-17900258
]
Ben Weidig commented on TAP5-2799:
----------------------------------
While taking with a colleague about the issue, we looked at more code and found
the documentation for
{{org.apache.tapestry5.http.TapestryHttpSymbolConstants.SESSION_LOCKING_ENABLED}}
which mentions a write-lock on {{{}getAttribute{}}}, so it doesn't seem to be
an oversight/bug:
{code:java}
/**
* If true (the default), then Tapestry will apply locking semantics around
access to the {@link javax.servlet.http.HttpSession}.
* Reading attribute names occurs with a shared read lock; getting or setting
an attribute upgrades to an exclusive write lock.
* This can tend to serialize threads when a number of simultaneous (Ajax)
requests from the client arrive ... however,
* many implementations of HttpSession are not thread safe, and often mutable
objects are stored in the session and shared
* between threads. Leaving this on the default will yield a more robust
application; setting it to false may speed
* up processing for more Ajax intensive applications (but care should then be
given to ensuring that objects shared inside
* the session are themselves immutable or thread-safe).
*
* @since 5.4
*/
{code}
If you want to get a better understanding what's happening at the deadlock, you
could override
{{org.apache.tapestry5.http.internal.services.TapestrySessionFactory}} by
copying it and returning a custom {{SessionLock}} based on
{{TapestrySessionFactoryImpl.SessionLockImpl}} in the private
{{{}lockForSession(HttpSession){}}}, like adding logging and using a
fairness-policy for {{ReentrantReadWriteLock}} or lock with timeouts.
Still, this issue needs more investigation and a better way to upgrade the
locking if possible.
> Thread Lockup when trying to read from a Session Object
> -------------------------------------------------------
>
> Key: TAP5-2799
> URL: https://issues.apache.org/jira/browse/TAP5-2799
> Project: Tapestry 5
> Issue Type: Bug
> Components: tapestry-http
> Affects Versions: 5.8.7
> Reporter: Alex Craddock
> Priority: Major
>
> I am not 100% sure how to recreate this but one of our servers froze up on
> the 443 port, when I looked into it and checked a thread dump I noticed 24
> threads all in this stack.
>
>
> {code:java}
> "http-nio-443-exec-25" #95 daemon prio=5 os_prio=0 cpu=6249001.07ms
> elapsed=138173.76s tid=0x00007fd974035800 nid=0x6288f waiting on condition
> [0x00007fd929edb000]
> java.lang.Thread.State: WAITING (parking)
> at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
> - parking to wait for <0x000000047a350910> (a
> java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
> at
> java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:194)
> at
> java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt([email protected]/AbstractQueuedSynchronizer.java:885)
> at
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued([email protected]/AbstractQueuedSynchronizer.java:917)
> at
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire([email protected]/AbstractQueuedSynchronizer.java:1240)
> at
> java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock([email protected]/ReentrantReadWriteLock.java:959)
> at
> org.apache.tapestry5.http.internal.services.TapestrySessionFactoryImpl$SessionLockImpl.acquireWriteLock(TapestrySessionFactoryImpl.java:110)
> at
> org.apache.tapestry5.http.internal.services.SessionImpl.getAttribute(SessionImpl.java:50)
> at
> org.apache.tapestry5.http.internal.services.ClusteredSessionImpl.getAttribute(ClusteredSessionImpl.java:56)
> {code}
>
>
> Which seemed a bit odd to me. When I looked into the code for
> "org.apache.tapestry5.http.internal.services.SessionImpl" I noticed this
>
> {code:java}
> public Object getAttribute(String name) {
> this.lock.acquireWriteLock();
> return this.session.getAttribute(name);
> }
> public List<String> getAttributeNames() {
> this.lock.acquireReadLock();
> return InternalUtils.toList(this.session.getAttributeNames());
> }
> public void setAttribute(String name, Object value) {
> this.lock.acquireWriteLock();
> this.session.setAttribute(name, value);
> } {code}
> I am not sure why, but I think it's a bug that when you are calling
> getAttribute, that it should only apply a read lock rather than a write lock.
> Not sure if this will solve my issue but I think this should be looked into.
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)