From 7e350051cd6114f5f9154e9310fa00f81e380077 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Mon, 31 Mar 2008 18:21:10 +0000 Subject: [PATCH] improved conversation locking --- .../conversation/impl/ContainedConversation.java | 1 - .../impl/JdkConcurrentConversationLock.java | 16 +++++++++++++++- .../webflow/conversation/impl/LockException.java | 9 +++++++++ .../impl/UtilConcurrentConversationLock.java | 13 +++++++++++-- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/LockException.java diff --git a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/ContainedConversation.java b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/ContainedConversation.java index 9d5cdcb1..7e1fda3c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/ContainedConversation.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/ContainedConversation.java @@ -101,7 +101,6 @@ class ContainedConversation implements Conversation, Serializable { logger.debug("Unlocking conversation " + id); } lock.unlock(); - // re-bind the conversation container in the session // this is required to make session replication work correctly in // a clustered environment diff --git a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/JdkConcurrentConversationLock.java b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/JdkConcurrentConversationLock.java index 02d0ae25..ae6d7991 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/JdkConcurrentConversationLock.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/JdkConcurrentConversationLock.java @@ -16,6 +16,7 @@ package org.springframework.webflow.conversation.impl; import java.io.Serializable; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -32,8 +33,21 @@ class JdkConcurrentConversationLock implements ConversationLock, Serializable { */ private Lock lock = new ReentrantLock(); + private int timeoutSeconds = 30; + + public void setTimeoutSeconds(int timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } + public void lock() { - lock.lock(); + try { + boolean acquired = lock.tryLock(timeoutSeconds, TimeUnit.SECONDS); + if (!acquired) { + throw new LockException("Unable to acquire conversation lock after " + timeoutSeconds + " seconds"); + } + } catch (InterruptedException e) { + throw new IllegalStateException("Unable to acquire conversation lock - thread interrupted", e); + } } public void unlock() { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/LockException.java b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/LockException.java new file mode 100644 index 00000000..3607fc10 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/LockException.java @@ -0,0 +1,9 @@ +package org.springframework.webflow.conversation.impl; + +import org.springframework.webflow.conversation.ConversationException; + +public class LockException extends ConversationException { + public LockException(String message) { + super(message); + } +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/UtilConcurrentConversationLock.java b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/UtilConcurrentConversationLock.java index f3cc985c..d2c73616 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/UtilConcurrentConversationLock.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/conversation/impl/UtilConcurrentConversationLock.java @@ -34,15 +34,24 @@ class UtilConcurrentConversationLock implements ConversationLock { */ private final ReentrantLock lock = new ReentrantLock(); + private int timeoutMills; + + public void setTimeoutSeconds(int timeoutSeconds) { + this.timeoutMills = timeoutSeconds * 1000; + } + /** * Acquires the lock. * @throws SystemInterruptedException if the lock cannot be acquired due to interruption */ public void lock() { try { - lock.acquire(); + boolean acquired = lock.attempt(timeoutMills); + if (!acquired) { + throw new LockException("Unable to acquire conversation lock after " + timeoutMills / 1000 + " seconds"); + } } catch (InterruptedException e) { - throw new SystemInterruptedException("Unable to acquire lock.", e); + throw new SystemInterruptedException("Unable to acquire conversation lock - thread interrupted", e); } }