Repository: wicket
Updated Branches:
  refs/heads/master 6bda62d63 -> 3398764a7


[WICKET-6603] Asypc page/data store destroyed without hanging


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

Branch: refs/heads/master
Commit: 3398764a77a6bb92d4a8859c49280b8ede77a708
Parents: 6bda62d
Author: Maxim Solodovnik <solomax...@gmail.com>
Authored: Fri Oct 26 22:56:06 2018 +0700
Committer: Maxim Solodovnik <solomax...@gmail.com>
Committed: Fri Oct 26 22:56:06 2018 +0700

----------------------------------------------------------------------
 .../wicket/pageStore/AsynchronousDataStore.java | 61 ++++++++-----------
 .../wicket/pageStore/AsynchronousPageStore.java | 62 ++++++++------------
 2 files changed, 52 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/3398764a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousDataStore.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousDataStore.java
 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousDataStore.java
index 7c46a7a..f749354 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousDataStore.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousDataStore.java
@@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
  * It starts only one instance of {@link PageSavingRunnable} because all we 
need is to make the page
  * storing asynchronous. We don't want to write concurrently in the wrapped 
{@link IDataStore},
  * though it may happen in the extreme case when the queue is full. These 
cases should be avoided.
- * 
+ *
  * @author Matej Knopp
  */
 public class AsynchronousDataStore implements IDataStore
@@ -59,7 +59,7 @@ public class AsynchronousDataStore implements IDataStore
        /**
         * The page saving thread.
         */
-       private final Thread pageSavingThread;
+       private Thread pageSavingThread;
 
        /**
         * The wrapped {@link IDataStore} that actually stores that pages
@@ -79,7 +79,7 @@ public class AsynchronousDataStore implements IDataStore
 
        /**
         * Construct.
-        * 
+        *
         * @param dataStore
         *            the wrapped {@link IDataStore} that actually saved the 
data
         * @param capacity
@@ -91,8 +91,7 @@ public class AsynchronousDataStore implements IDataStore
                entries = new LinkedBlockingQueue<>(capacity);
                entryMap = new ConcurrentHashMap<>();
 
-               PageSavingRunnable savingRunnable = new 
PageSavingRunnable(dataStore, entries, entryMap);
-               pageSavingThread = new Thread(savingRunnable, 
"Wicket-AsyncDataStore-PageSavingThread");
+               pageSavingThread = new Thread(new PageSavingRunnable(), 
"Wicket-AsyncDataStore-PageSavingThread");
                pageSavingThread.setDaemon(true);
                pageSavingThread.start();
        }
@@ -100,12 +99,13 @@ public class AsynchronousDataStore implements IDataStore
        @Override
        public void destroy()
        {
-               if (pageSavingThread.isAlive())
+               final Thread thread = pageSavingThread;
+               pageSavingThread = null;
+               if (thread != null && thread.isAlive())
                {
-                       pageSavingThread.interrupt();
                        try
                        {
-                               pageSavingThread.join();
+                               thread.join();
                        } catch (InterruptedException e)
                        {
                                log.error(e.getMessage(), e);
@@ -117,7 +117,7 @@ public class AsynchronousDataStore implements IDataStore
 
        /**
         * Little helper
-        * 
+        *
         * @param sessionId
         * @param id
         * @return Entry
@@ -192,12 +192,16 @@ public class AsynchronousDataStore implements IDataStore
        /**
         * Save the entry in the queue if there is a room or directly pass it 
to the wrapped
         * {@link IDataStore} if there is no such
-        * 
+        *
         * @see 
org.apache.wicket.pageStore.IDataStore#storeData(java.lang.String, int, byte[])
         */
        @Override
        public void storeData(final String sessionId, final int id, final 
byte[] data)
        {
+               if (pageSavingThread == null)
+               {
+                       return;
+               }
                Entry entry = new Entry(sessionId, id, data);
                String key = getKey(entry);
                entryMap.put(key, entry);
@@ -216,13 +220,16 @@ public class AsynchronousDataStore implements IDataStore
                catch (InterruptedException e)
                {
                        log.error(e.getMessage(), e);
-                       entryMap.remove(key);
-                       dataStore.storeData(sessionId, id, data);
+                       if (pageSavingThread != null)
+                       {
+                               entryMap.remove(key);
+                               dataStore.storeData(sessionId, id, data);
+                       }
                }
        }
 
        /**
-        * 
+        *
         * @param pageId
         * @param sessionId
         * @return generated key
@@ -233,7 +240,7 @@ public class AsynchronousDataStore implements IDataStore
        }
 
        /**
-        * 
+        *
         * @param entry
         * @return generated key
         */
@@ -301,28 +308,12 @@ public class AsynchronousDataStore implements IDataStore
        /**
         * The thread that acts as consumer of {@link Entry}ies
         */
-       private static class PageSavingRunnable implements Runnable
+       private class PageSavingRunnable implements Runnable
        {
-               private static final Logger log = 
LoggerFactory.getLogger(PageSavingRunnable.class);
-
-               private final BlockingQueue<Entry> entries;
-
-               private final ConcurrentMap<String, Entry> entryMap;
-
-               private final IDataStore dataStore;
-
-               private PageSavingRunnable(IDataStore dataStore, 
BlockingQueue<Entry> entries,
-                       ConcurrentMap<String, Entry> entryMap)
-               {
-                       this.dataStore = dataStore;
-                       this.entries = entries;
-                       this.entryMap = entryMap;
-               }
-
                @Override
                public void run()
                {
-                       while (!Thread.interrupted())
+                       while (pageSavingThread != null)
                        {
                                Entry entry = null;
                                try
@@ -331,12 +322,12 @@ public class AsynchronousDataStore implements IDataStore
                                }
                                catch (InterruptedException e)
                                {
-                                       Thread.currentThread().interrupt();
+                                       log.debug("PageSavingRunnable:: 
Interrupted...");
                                }
 
-                               if (entry != null)
+                               if (entry != null && pageSavingThread != null)
                                {
-                                       log.debug("Saving asynchronously: 
{}...", entry);
+                                       log.debug("PageSavingRunnable:: Saving 
asynchronously: {}...", entry);
                                        dataStore.storeData(entry.sessionId, 
entry.pageId, entry.data);
                                        entryMap.remove(getKey(entry));
                                }

http://git-wip-us.apache.org/repos/asf/wicket/blob/3398764a/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 43993ba..c24b2a0 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
@@ -39,9 +39,9 @@ import org.slf4j.LoggerFactory;
  * It starts only one instance of {@link PageSavingRunnable} because all we 
need is to make the page
  * storing asynchronous. We don't want to write concurrently in the wrapped 
{@link IPageStore},
  * though it may happen in the extreme case when the queue is full. These 
cases should be avoided.
- * 
+ *
  * Based on AsynchronousDataStore (@author Matej Knopp).
- * 
+ *
  * @author manuelbarzi
  */
 public class AsynchronousPageStore implements IPageStore
@@ -63,7 +63,7 @@ public class AsynchronousPageStore implements IPageStore
        /**
         * The page saving thread.
         */
-       private final Thread pageSavingThread;
+       private Thread pageSavingThread;
 
        /**
         * The wrapped {@link IPageStore} that actually stores that pages
@@ -83,7 +83,7 @@ public class AsynchronousPageStore implements IPageStore
 
        /**
         * Construct.
-        * 
+        *
         * @param delegate
         *            the wrapped {@link IPageStore} that actually saved the 
page
         * @param capacity
@@ -95,15 +95,14 @@ public class AsynchronousPageStore implements IPageStore
                entries = new LinkedBlockingQueue<>(capacity);
                entryMap = new ConcurrentHashMap<>();
 
-               PageSavingRunnable savingRunnable = new 
PageSavingRunnable(delegate, entries, entryMap);
-               pageSavingThread = new Thread(savingRunnable, 
"Wicket-AsyncPageStore-PageSavingThread");
+               pageSavingThread = new Thread(new PageSavingRunnable(), 
"Wicket-AsyncPageStore-PageSavingThread");
                pageSavingThread.setDaemon(true);
                pageSavingThread.start();
        }
 
        /**
         * Little helper
-        * 
+        *
         * @param sessionId
         * @param pageId
         * @return Entry
@@ -114,7 +113,7 @@ public class AsynchronousPageStore implements IPageStore
        }
 
        /**
-        * 
+        *
         * @param pageId
         * @param sessionId
         * @return generated key
@@ -125,7 +124,7 @@ public class AsynchronousPageStore implements IPageStore
        }
 
        /**
-        * 
+        *
         * @param entry
         * @return generated key
         */
@@ -186,28 +185,12 @@ public class AsynchronousPageStore implements IPageStore
        /**
         * The thread that acts as consumer of {@link Entry}ies
         */
-       private static class PageSavingRunnable implements Runnable
+       private class PageSavingRunnable implements Runnable
        {
-               private static final Logger log = 
LoggerFactory.getLogger(PageSavingRunnable.class);
-
-               private final BlockingQueue<Entry> entries;
-
-               private final ConcurrentMap<String, Entry> entryMap;
-
-               private final IPageStore delegate;
-
-               private PageSavingRunnable(IPageStore delegate, 
BlockingQueue<Entry> entries,
-                                          ConcurrentMap<String, Entry> 
entryMap)
-               {
-                       this.delegate = delegate;
-                       this.entries = entries;
-                       this.entryMap = entryMap;
-               }
-
                @Override
                public void run()
                {
-                       while (!Thread.interrupted())
+                       while (pageSavingThread != null)
                        {
                                Entry entry = null;
                                try
@@ -216,12 +199,12 @@ public class AsynchronousPageStore implements IPageStore
                                }
                                catch (InterruptedException e)
                                {
-                                       Thread.currentThread().interrupt();
+                                       log.debug("PageSavingRunnable:: 
Interrupted...");
                                }
 
-                               if (entry != null)
+                               if (entry != null && pageSavingThread != null)
                                {
-                                       log.debug("Saving asynchronously: 
{}...", entry);
+                                       log.debug("PageSavingRunnable:: Saving 
asynchronously: {}...", entry);
                                        delegate.storePage(entry.sessionId, 
entry.page);
                                        entryMap.remove(getKey(entry));
                                }
@@ -232,19 +215,19 @@ public class AsynchronousPageStore implements IPageStore
        @Override
        public void destroy()
        {
-               if (pageSavingThread.isAlive())
+               final Thread thread = pageSavingThread;
+               pageSavingThread = null;
+               if (thread != null && thread.isAlive())
                {
-                       pageSavingThread.interrupt();
                        try
                        {
-                               pageSavingThread.join();
+                               thread.join();
                        }
                        catch (InterruptedException e)
                        {
                                log.error(e.getMessage(), e);
                        }
                }
-
                delegate.destroy();
        }
 
@@ -286,6 +269,10 @@ public class AsynchronousPageStore implements IPageStore
        @Override
        public void storePage(String sessionId, IManageablePage page)
        {
+               if (pageSavingThread == null)
+               {
+                       return;
+               }
                Entry entry = new Entry(sessionId, page);
                String key = getKey(entry);
                entryMap.put(key, entry);
@@ -308,8 +295,11 @@ public class AsynchronousPageStore implements IPageStore
                catch (InterruptedException e)
                {
                        log.error(e.getMessage(), e);
-                       entryMap.remove(key);
-                       delegate.storePage(sessionId, page);
+                       if (pageSavingThread != null)
+                       {
+                               entryMap.remove(key);
+                               delegate.storePage(sessionId, page);
+                       }
                }
        }
 

Reply via email to