You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wicket.apache.org by GitBox <gi...@apache.org> on 2020/03/05 10:12:02 UTC

[GitHub] [wicket] theigl commented on a change in pull request #411: WICKET-6751 Page synchronizer strategies

theigl commented on a change in pull request #411: WICKET-6751 Page synchronizer strategies
URL: https://github.com/apache/wicket/pull/411#discussion_r388195392
 
 

 ##########
 File path: wicket-core/src/main/java/org/apache/wicket/page/DefaultPageLockManager.java
 ##########
 @@ -0,0 +1,201 @@
+package org.apache.wicket.page;
+
+import java.io.Serializable;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Supplier;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.settings.ExceptionSettings;
+import org.apache.wicket.util.LazyInitializer;
+import org.apache.wicket.util.lang.Threads;
+import org.apache.wicket.util.time.Durations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default {@link IPageLockManager} that that holds a map of locks in the current session.
+ * 
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class DefaultPageLockManager implements IPageLockManager, Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final Logger logger = LoggerFactory.getLogger(DefaultPageLockManager.class);
+
+	/** map of which pages are owned by which threads */
+	private final Supplier<ConcurrentMap<Integer, PageAccessSynchronizer.PageLock>> locks = new LazyInitializer<ConcurrentMap<Integer, PageAccessSynchronizer.PageLock>>()
+	{
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected ConcurrentMap<Integer, PageAccessSynchronizer.PageLock> createInstance()
+		{
+			return new ConcurrentHashMap<>();
+		}
+	};
+
+	/** timeout value for acquiring a page lock */
+	private final Duration timeout;
+
+	/**
+	 * Constructor
+	 *
+	 * @param timeout
+	 *            timeout value for acquiring a page lock
+	 */
+	public DefaultPageLockManager(Duration timeout)
+	{
+		this.timeout = timeout;
+	}
+
+	private static long remaining(Instant start, Duration timeout)
+	{
+		Duration elapsedTime = Durations.elapsedSince(start);
+		return Math.max(0, timeout.minus(elapsedTime).toMillis());
+	}
+
+	/**
+	 * @param pageId
+	 *            the id of the page to be locked
+	 * @return the duration for acquiring a page lock
+	 */
+	public Duration getTimeout(int pageId)
+	{
+		return timeout;
+	}
+
+	@Override
+	public void lockPage(int pageId) throws CouldNotLockPageException
+	{
+		final Thread thread = Thread.currentThread();
+		final PageAccessSynchronizer.PageLock lock = new PageAccessSynchronizer.PageLock(pageId, thread);
+		final Instant start = Instant.now();
+
+		boolean locked = false;
+
+		final boolean isDebugEnabled = logger.isDebugEnabled();
+
+		PageAccessSynchronizer.PageLock previous = null;
+
+		Duration timeout = getTimeout(pageId);
+
+		while (!locked && Durations.elapsedSince(start).compareTo(timeout) < 0)
+		{
+			if (isDebugEnabled)
+			{
+				logger.debug("'{}' attempting to acquire lock to page with id '{}'",
+						thread.getName(), pageId);
+			}
+
+			previous = locks.get().putIfAbsent(pageId, lock);
+
+			if (previous == null || previous.getThread() == thread)
+			{
+				// first thread to acquire lock or lock is already owned by this thread
+				locked = true;
+			}
+			else
+			{
+				// wait for a lock to become available
+				long remaining = remaining(start, timeout);
+				if (remaining > 0)
+				{
+					previous.waitForRelease(remaining, isDebugEnabled);
+				}
+			}
+		}
+		if (locked)
 
 Review comment:
   Done

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services