You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2018/07/07 19:25:09 UTC

wicket git commit: WICKET-6563 IPageContext set synchronization

Repository: wicket
Updated Branches:
  refs/heads/WICKET-6563 2f70db06d -> 7e9c7e516


WICKET-6563 IPageContext set synchronization

prevent multiple threads from settings data into IPageContext
concurrently

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/7e9c7e51
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/7e9c7e51
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/7e9c7e51

Branch: refs/heads/WICKET-6563
Commit: 7e9c7e5166fda6692163c9551dc56d3177acfe6d
Parents: 2f70db0
Author: Sven Meier <sv...@apache.org>
Authored: Sat Jul 7 20:37:54 2018 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Sat Jul 7 21:03:02 2018 +0200

----------------------------------------------------------------------
 .../wicket/DefaultPageManagerProvider.java      | 22 +++++++-------------
 .../org/apache/wicket/IPageManagerProvider.java |  5 +++++
 .../org/apache/wicket/page/IPageManager.java    |  2 ++
 .../org/apache/wicket/page/PageManager.java     |  8 ++++---
 .../wicket/pageStore/AsynchronousPageStore.java |  4 ++--
 .../wicket/pageStore/CryptingPageStore.java     |  8 +++----
 .../wicket/pageStore/DefaultPageContext.java    | 13 ++++++++++--
 .../wicket/pageStore/GroupingPageStore.java     |  7 ++++---
 .../apache/wicket/pageStore/IPageContext.java   | 18 +++++++++++++---
 .../wicket/pageStore/InSessionPageStore.java    |  5 ++---
 .../apache/wicket/pageStore/SerializedPage.java |  8 +++++--
 .../wicket/page/PersistentPageManagerTest.java  |  4 +++-
 .../wicket/pageStore/DummyPageContext.java      |  4 +++-
 .../wicket/pageStore/GroupingPageStoreTest.java |  4 ++--
 14 files changed, 71 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
index 9668309..c453be9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
+++ b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
@@ -38,38 +38,29 @@ import org.apache.wicket.util.lang.Bytes;
 
 /**
  * A provider of a {@link PageManager} with a default chain of page {@link IPageStore}s:
- * <ul>
+ * <ol>
  * <li>{@link RequestPageStore} caching pages until end of the request</li>
  * <li>{@link InSessionPageStore} keeping the last accessed page in the session</li>
  * <li>{@link AsynchronousPageStore} moving storage of pages to a worker thread (if enabled in
  * {@link StoreSettings#isAsynchronous()})</li>
  * <li>{@link DiskPageStore} keeping all pages, configured according to {@link StoreSettings}</li>
- * </ul>
+ * </ol>
  * An alternative chain with all pages held in-memory could be:
- * <ul>
+ * <pl>
  * <li>{@link RequestPageStore} caching pages until end of the request</li>
  * <li>{@link InSessionPageStore} keeping the last accessed page in the session</li>
  * <li>{@link AsynchronousPageStore} moving storage of pages to a worker thread</li>
  * <li>{@link SerializingPageStore} serializing all pages (so they are available for
  * back-button)</li>
  * <li>{@link InMemoryPageStore} keeping all pages in memory</li>
- * </ul>
+ * </ol>
  * ... or if all pages should be kept in the session only, without any serialization (no back-button
  * support though):
- * <ul>
+ * <ol>
  * <li>{@link RequestPageStore} caching pages until end of the request</li>
  * <li>{@link InSessionPageStore} keeping a limited count of pages in the session, e.g. 10</li>
  * <li>{@link NoopPageStore} discarding all exceeding pages</li>
- * </ul>
- * ... or if pages should be kept encrypted on disk:
- * <ul>
- * <li>{@link RequestPageStore} caching pages until end of the request</li>
- * <li>{@link InSessionPageStore} keeping the last accessed page in the session</li>
- * <li>{@link AsynchronousPageStore} moving storage of pages to a worker thread</li>
- * <li>{@link SerializingPageStore} serializing all pages, as required by the following ...</li>
- * <li>{@link CryptingPageStore} encrypting and decrypting all pages</li>
- * <li>{@link DiskPageStore} without {@link ISerializer} as required by the previous</li>
- * </ul>
+ * </ol>
  * For back-button support <em>at least one</em> store in the chain must create copies of stored
  * pages (usually through serialization), otherwise any following request will work on an identical
  * page instance and the previous state of page is no longer accessible.
@@ -77,6 +68,7 @@ import org.apache.wicket.util.lang.Bytes;
  * Other stores be may inserted ad libitum, e.g.
  * <ul>
  * <li>{@link GroupingPageStore} groups pages with their own maximum page limit</li>
+ * <li>{@link CryptingPageStore} encrypting all pages - read its documentation on what restrictions it poses on the chain of stores</li>
  * </ul>
  */
 public class DefaultPageManagerProvider implements IPageManagerProvider

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/IPageManagerProvider.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/IPageManagerProvider.java b/wicket-core/src/main/java/org/apache/wicket/IPageManagerProvider.java
index ce40fcc..d887af3 100644
--- a/wicket-core/src/main/java/org/apache/wicket/IPageManagerProvider.java
+++ b/wicket-core/src/main/java/org/apache/wicket/IPageManagerProvider.java
@@ -20,6 +20,11 @@ import java.util.function.Supplier;
 
 import org.apache.wicket.page.IPageManager;
 
+/**
+ * Provider of an {@link IPageManager}.
+ * 
+ * @author svenmeier
+ */
 public interface IPageManagerProvider extends Supplier<IPageManager>
 {
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/page/IPageManager.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/page/IPageManager.java b/wicket-core/src/main/java/org/apache/wicket/page/IPageManager.java
index 9d517df..d600eee 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/IPageManager.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/IPageManager.java
@@ -21,6 +21,8 @@ import org.apache.wicket.pageStore.IPageStore;
 
 /**
  * A manager of pages - facade between {@link Page}s and {@link IPageStore}s they are stored in.
+ * 
+ * @see PageManager
  */
 public interface IPageManager
 {

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/page/PageManager.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/page/PageManager.java b/wicket-core/src/main/java/org/apache/wicket/page/PageManager.java
index ab58c41..a516e1f 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/PageManager.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/PageManager.java
@@ -16,7 +16,6 @@
  */
 package org.apache.wicket.page;
 
-import org.apache.wicket.Application;
 import org.apache.wicket.Session;
 import org.apache.wicket.pageStore.DefaultPageContext;
 import org.apache.wicket.pageStore.IPageContext;
@@ -24,7 +23,10 @@ import org.apache.wicket.pageStore.IPageStore;
 import org.apache.wicket.util.lang.Args;
 
 /**
- * A manager of pages, i.e. a mediator between an {@link Application} and an {@link IPageStore}.
+ * Default implementation of a page mmanager.
+ * 
+ * @see IPageStore
+ * @see IPageContext
  */
 public class PageManager implements IPageManager
 {
@@ -67,7 +69,7 @@ public class PageManager implements IPageManager
 	/**
 	 * Factory method for an {@link IPageContext}, returns a {@link DefaultPageContext} by default.
 	 * 
-	 * @return
+	 * @return context of a stored page
 	 */
 	protected IPageContext createPageContext()
 	{

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
index 3428d02..780dafa 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
@@ -236,13 +236,13 @@ public class AsynchronousPageStore extends DelegatingPageStore
 		 * Prevents access to the session when called asynchronously.
 		 */
 		@Override
-		public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+		public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 		{
 			if (asynchronous) {
 				throw new WicketRuntimeException("no session available asynchronuously");
 			}
 			
-			context.setSessionData(key, value);
+			return context.setSessionData(key, value);
 		}
 
 		/**

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
index c77a4b6..e1014d8 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
@@ -39,7 +39,7 @@ import org.apache.wicket.serialize.ISerializer;
  * <ul>
  * <li>a {@link SerializingPageStore} delegating to this store and</li>
  * <li>delegating to a store that does not deserialize its pages, e.g. a {@link DiskPageStore}
- * without {@link ISerializer}</li>.
+ * without an {@link ISerializer}</li>.
  * </ul>
  */
 public class CryptingPageStore extends DelegatingPageStore
@@ -67,7 +67,7 @@ public class CryptingPageStore extends DelegatingPageStore
 	}
 
 	/**
-	 * Supports asynchronous add if the delegate supports it.
+	 * Supports asynchronous {@link #addPage(IPageContext, IManageablePage)} if the delegate supports it.
 	 */
 	@Override
 	public boolean canBeAsynchronous(IPageContext context)
@@ -84,9 +84,9 @@ public class CryptingPageStore extends DelegatingPageStore
 		SessionData data = context.getSessionData(KEY);
 		if (data == null)
 		{
-			data = new SessionData(createCipherKey(context));
+			context.bind();
 
-			context.setSessionData(KEY, data);
+			data = context.setSessionData(KEY, new SessionData(createCipherKey(context)));
 		}
 		return data;
 	}

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/DefaultPageContext.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/DefaultPageContext.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/DefaultPageContext.java
index 257f593..971866e 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/DefaultPageContext.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/DefaultPageContext.java
@@ -74,9 +74,18 @@ public class DefaultPageContext implements IPageContext
 	}
 
 	@Override
-	public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+	public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 	{
-		session.setMetaData(key, value);
+		synchronized (session)
+		{
+			T oldValue = session.getMetaData(key);
+			if (oldValue != null) {
+				return oldValue;
+			}
+			
+			session.setMetaData(key, value);
+			return value;
+		}
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/GroupingPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/GroupingPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/GroupingPageStore.java
index 1771763..c06d18a 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/GroupingPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/GroupingPageStore.java
@@ -135,9 +135,8 @@ public abstract class GroupingPageStore extends DelegatingPageStore
 		if (data == null)
 		{
 			context.bind();
-			data = new SessionData();
 
-			context.setSessionData(KEY, data);
+			data = context.setSessionData(KEY, new SessionData());
 		}
 
 		return data;
@@ -244,9 +243,11 @@ public abstract class GroupingPageStore extends DelegatingPageStore
 		}
 
 		@Override
-		public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+		public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 		{
 			sessionData.setMetaData(group, key, value);
+			
+			return value;
 		}
 
 		@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageContext.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageContext.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageContext.java
index 5b9fcfb..7dff1a5 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageContext.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageContext.java
@@ -70,14 +70,26 @@ public interface IPageContext
 	<T extends Serializable> T getSessionAttribute(String key);
 
 	/**
-	 * Set data into the session.
-	 * 
+	 * Set data into the session - only if it is not set already.
+	 * <p>
+	 * Recommended usage:
+	 * <pre>
+	 * <code>
+	 * SessionData data = context.getSessionData(KEY);
+	 * if (data == null)
+	 * {
+	 *     data = context.setSessionData(KEY, new SessionData());
+	 * }
+	 * </code>
+	 * </pre>
+	 *
 	 * @param key
 	 *            key
 	 * @param value
 	 *            value
+	 * @return the old value if already present, or the new value
 	 */
-	<T extends Serializable> void setSessionData(MetaDataKey<T> key, T value);
+	<T extends Serializable> T setSessionData(MetaDataKey<T> key, T value);
 
 	/**
 	 * Get data from the session.

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
index ad09b6f..e526155 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
@@ -47,7 +47,7 @@ public class InSessionPageStore extends DelegatingPageStore
 		private static final long serialVersionUID = 1L;
 	};
 
-	private ISerializer serializer;
+	private final ISerializer serializer;
 
 	private int maxPages;
 	
@@ -138,9 +138,8 @@ public class InSessionPageStore extends DelegatingPageStore
 		if (data == null)
 		{
 			context.bind();
-			data = new SessionData();
 
-			context.setSessionData(KEY, data);
+			data = context.setSessionData(KEY, new SessionData());
 		}
 
 		// data might be deserialized so initialize again

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
index 8ebe559..5d858b5 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/SerializedPage.java
@@ -22,8 +22,12 @@ import org.apache.wicket.util.lang.Args;
 /**
  * A wrapper around a serialized page.
  * <p>
- * An {@link IPageStore} might choose to use this representation of a page internally,
- * or accept it in {@link IPageStore#addPage(IPageContext, IManageablePage)}.
+ * An {@link IPageStore} might use this representation of a page internally,
+ * accept it in {@link IPageStore#addPage(IPageContext, IManageablePage)} or delegate it
+ * to another store.
+ * <p>
+ * Stores might pose restrictions on what type of pages they work with, see {@link CryptingPageStore}
+ * for an example.
  * 
  * @see SerializingPageStore
  */

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/test/java/org/apache/wicket/page/PersistentPageManagerTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/page/PersistentPageManagerTest.java b/wicket-core/src/test/java/org/apache/wicket/page/PersistentPageManagerTest.java
index af8c73f..1ace989 100644
--- a/wicket-core/src/test/java/org/apache/wicket/page/PersistentPageManagerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/page/PersistentPageManagerTest.java
@@ -116,11 +116,13 @@ public class PersistentPageManagerTest
 			{
 				return new DummyPageContext() {
 					@Override
-					public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+					public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 					{
 						super.setSessionData(key, value);
 						
 						sessionData.set(value);
+						
+						return value;
 					}
 					
 					@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/test/java/org/apache/wicket/pageStore/DummyPageContext.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/pageStore/DummyPageContext.java b/wicket-core/src/test/java/org/apache/wicket/pageStore/DummyPageContext.java
index 250e544..88fbb06 100644
--- a/wicket-core/src/test/java/org/apache/wicket/pageStore/DummyPageContext.java
+++ b/wicket-core/src/test/java/org/apache/wicket/pageStore/DummyPageContext.java
@@ -74,9 +74,11 @@ public class DummyPageContext implements IPageContext
 	}
 	
 	@Override
-	public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+	public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 	{
 		sessionData = key.set(sessionData, value);
+		
+		return value;
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/7e9c7e51/wicket-core/src/test/java/org/apache/wicket/pageStore/GroupingPageStoreTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/pageStore/GroupingPageStoreTest.java b/wicket-core/src/test/java/org/apache/wicket/pageStore/GroupingPageStoreTest.java
index b863074..1bdf9a1 100644
--- a/wicket-core/src/test/java/org/apache/wicket/pageStore/GroupingPageStoreTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/pageStore/GroupingPageStoreTest.java
@@ -80,11 +80,11 @@ public class GroupingPageStoreTest
 		
 		DummyPageContext context = new DummyPageContext(sessionId) {
 			@Override
-			public <T extends Serializable> void setSessionData(MetaDataKey<T> key, T value)
+			public <T extends Serializable> T setSessionData(MetaDataKey<T> key, T value)
 			{
 				assertFalse("session not set directly in session", value == VALUE);
 				
-				super.setSessionData(key, value);
+				return super.setSessionData(key, value);
 			}
 			
 			@Override