You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by eh...@apache.org on 2007/04/07 02:18:47 UTC
svn commit: r526326 -
/incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java
Author: ehillenius
Date: Fri Apr 6 17:18:46 2007
New Revision: 526326
URL: http://svn.apache.org/viewvc?view=rev&rev=526326
Log:
sorted members
Modified:
incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java
Modified: incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java?view=diff&rev=526326&r1=526325&r2=526326
==============================================================================
--- incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java (original)
+++ incubator/wicket/branches/wicket-1.x/jdk-1.4/wicket/src/main/java/wicket/protocol/http/FilePageStore.java Fri Apr 6 17:18:46 2007
@@ -48,378 +48,224 @@
*/
public class FilePageStore implements IPageStore
{
- /** log. */
- protected static Log log = LogFactory.getLog(FilePageStore.class);
-
- private static final Object SERIALIZING = new Object();
-
- private final File defaultWorkDir;
-
- private final PageSerializingThread serThread;
- private final ConcurrentHashMap pagesToBeSerialized;
-
-
- private final PageSavingThread saveThread;
- private final ConcurrentHashMap pagesToBeSaved;
-
-
- private final String appName;
-
- private volatile int serialized;
- private volatile long totalSerializationTime = 0;
-
- /**
- * Construct.
- */
- public FilePageStore()
- {
- this((File)((WebApplication)Application.get()).getServletContext().getAttribute(
- "javax.servlet.context.tempdir"));
- }
-
- /**
- * Construct.
- *
- * @param dir
- * The directory to save to.
- */
- public FilePageStore(File dir)
+ private class PageSavingThread implements Runnable
{
- defaultWorkDir = new File(dir, "sessions/");
- defaultWorkDir.mkdirs();
-
- pagesToBeSerialized = new ConcurrentHashMap();
- pagesToBeSaved = new ConcurrentHashMap();
- appName = Application.get().getApplicationKey();
-
- saveThread = new PageSavingThread();
- Thread t = new Thread(saveThread, "FilePageSavingThread-" + appName);
- t.setDaemon(true);
- t.setPriority(Thread.MAX_PRIORITY);
- t.start();
-
- serThread = new PageSerializingThread();
- t = new Thread(serThread, "FilePageSerializingThread-" + appName);
- t.setDaemon(true);
- t.setPriority(Thread.NORM_PRIORITY);
- t.start();
-
- log.info("storing sessions in " + dir + "/sessions");
- }
+ private volatile boolean stop = false;
+ private long totalSavingTime = 0;
+ private int saved;
+ private int bytesSaved;
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#getPage(java.lang.String,
- * int, int)
- */
- public Page getPage(String sessionId, String pagemapName, int id, int versionNumber,
- int ajaxVersionNumber)
- {
- SessionPageKey currentKey = new SessionPageKey(sessionId, id, versionNumber,
- ajaxVersionNumber, pagemapName, null);
- long t = System.currentTimeMillis();
- byte[] bytes = testMap(currentKey);
- if (bytes != null)
- {
- Page page = (Page)Objects.byteArrayToObject(bytes);
- page = page.getVersion(versionNumber);
- return page;
- }
- File sessionDir = new File(getWorkDir(), sessionId);
- if (sessionDir.exists())
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ public void run()
{
- File pageFile = getPageFile(currentKey, sessionDir);
- if (pageFile.exists())
+ while (!stop)
{
- long t1 = System.currentTimeMillis();
- FileInputStream fis = null;
try
{
- byte[] pageData = null;
- fis = new FileInputStream(pageFile);
- int length = (int)pageFile.length();
- ByteBuffer bb = ByteBuffer.allocate(length);
- fis.getChannel().read(bb);
- if (bb.hasArray())
- {
- pageData = bb.array();
- }
- else
- {
- pageData = new byte[length];
- bb.get(pageData);
- }
- long t2 = System.currentTimeMillis();
- Page page = (Page)Objects.byteArrayToObject(pageData);
- page = page.getVersion(versionNumber);
- if (page != null && log.isDebugEnabled())
+ while (pagesToBeSaved.size() == 0)
{
- long t3 = System.currentTimeMillis();
- log.debug("restoring page " + page.getClass() + "[" + page.getNumericId()
- + "," + page.getCurrentVersionNumber() + "] size: "
- + pageData.length + " for session " + sessionId + " took "
- + (t2 - t1) + " miliseconds to read in and " + (t3 - t2)
- + " miliseconds to deserialize");
+ Thread.sleep(2000);
+ if (stop)
+ return;
}
- return page;
- }
- catch (Exception e)
- {
- log.debug("Error loading page " + id + "," + versionNumber
- + " for the sessionid " + sessionId + " from disk", e);
- }
- finally
- {
- try
+ // if ( pagesToBeSaved.size() > 100)
+ // {
+ // System.err.println("max");
+ // Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ // }
+ // else if ( pagesToBeSaved.size() > 25)
+ // {
+ // System.err.println("normal");
+ // Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
+ // }
+ // else
+ // {
+ // System.err.println("min");
+ // Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
+ // }
+ Iterator it = pagesToBeSaved.entrySet().iterator();
+ while (it.hasNext())
{
- if (fis != null)
+ Map.Entry entry = (Entry)it.next();
+ SessionPageKey key = (SessionPageKey)entry.getKey();
+ if (key.data instanceof byte[])
{
- fis.close();
+ savePage(key, (byte[])key.data);
}
- }
- catch (IOException ex)
- {
- // ignore
+ it.remove();
}
}
- }
- }
- return null;
- }
-
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#removePage(java.lang.String,
- * wicket.Page)
- */
- public void removePage(String sessionId, Page page)
- {
- removePageFromPendingMap(sessionId, page.getNumericId());
- }
-
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#storePage(java.lang.String,
- * wicket.Page)
- */
- public void storePage(String sessionId, Page page)
- {
- List list = (List)pagesToBeSerialized.get(sessionId);
- if (list == null)
- {
- list = new LinkedList();
- }
- synchronized (list)
- {
- list.add(new SessionPageKey(sessionId, page));
- }
- // do really put it back in.. The writer thread could have removed it.
- pagesToBeSerialized.put(sessionId, list);
- }
-
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#pageAccessed(java.lang.String,
- * wicket.Page)
- */
- public void pageAccessed(String sessionId, Page page)
- {
- SessionPageKey currentKey = new SessionPageKey(sessionId, page);
- testMap(currentKey);
- }
-
-
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#destroy()
- */
- public void destroy()
- {
- saveThread.stop();
- serThread.stop();
- }
-
- private byte[] testMap(SessionPageKey currentKey)
- {
- SessionPageKey previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
- if (previousPage != null)
- {
- return (byte[])previousPage.data;
- }
- List list = (List)pagesToBeSerialized.get(currentKey.sessionId);
-
- if (list == null)
- return null;
-
- synchronized (list)
- {
- int index = list.indexOf(currentKey);
- if (index != -1)
- {
- currentKey = (SessionPageKey)list.get(index);
- Object object = currentKey.data;
- if (object instanceof Page)
- {
- list.remove(index);
- }
- else if (object == SERIALIZING)
+ catch (Exception e)
{
- try
- {
- list.wait();
- }
- catch (InterruptedException ex)
- {
- throw new RuntimeException(ex);
- }
- object = currentKey.data;
- if (object instanceof byte[])
- {
- return (byte[])object;
- }
- else
- {
- previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
- if (previousPage != null)
- {
- return (byte[])previousPage.data;
- }
- return null;
- }
- }
- }
- else
- {
- return null;
- }
- }
-
- byte[] bytes = serializePage(currentKey, (Page)currentKey.data);
- if (bytes != null)
- {
- currentKey.setObject(bytes);
- pagesToBeSaved.put(currentKey, currentKey);
- }
- return bytes;
- }
-
-
- /**
- * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#unbind(java.lang.String)
- */
- public void unbind(String sessionId)
- {
- removeSessionFromPendingMap(sessionId);
- }
+ log.error("Error in page save thread", e);
+ }
+ }
+ }
- private void removeSessionFromPendingMap(String sessionId)
- {
- pagesToBeSerialized.remove(sessionId);
- // TODO remove from pagesToBeSaved..
- removeSession(sessionId);
+ /**
+ * Stops this thread.
+ */
+ public void stop()
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Total time in saving: " + totalSavingTime);
+ log.debug("Bytes saved: " + bytesSaved);
+ log.debug("Pages saved: " + saved);
+ }
+ stop = true;
+ }
- }
- private void removeSession(String sessionId)
- {
- File sessionDir = new File(getWorkDir(), sessionId);
- if (sessionDir.exists())
+ /**
+ * @param sessionId
+ * @param key
+ * @param bytes
+ */
+ private void savePage(SessionPageKey key, byte[] bytes)
{
- File[] files = sessionDir.listFiles();
- if (files != null)
+ File sessionDir = new File(getWorkDir(), key.sessionId);
+ sessionDir.mkdirs();
+ File pageFile = getPageFile(key, sessionDir);
+
+ FileOutputStream fos = null;
+ long t1 = System.currentTimeMillis();
+ int length = 0;
+ try
{
- for (int i = 0; i < files.length; i++)
+ fos = new FileOutputStream(pageFile);
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ fos.getChannel().write(bb);
+ length = bytes.length;
+ }
+ catch (Exception e)
+ {
+ log.error("Error saving page " + key.pageClass + " [" + key.id + ","
+ + key.versionNumber + "] for the sessionid " + key.sessionId);
+ }
+ finally
+ {
+ try
{
- files[i].delete();
+ if (fos != null)
+ {
+ fos.close();
+ }
+ }
+ catch (IOException ex)
+ {
+ // ignore
}
}
- if (!sessionDir.delete())
+ long t3 = System.currentTimeMillis();
+ if (log.isDebugEnabled())
{
- sessionDir.deleteOnExit();
+ log.debug("storing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
+ + "] size: " + length + " for session " + key.sessionId + " took "
+ + (t3 - t1) + " miliseconds to save");
}
+ totalSavingTime += (t3 - t1);
+ saved++;
+ bytesSaved += length;
}
+
}
- /**
- * @param sessionId
- * @param id
- */
- private void removePageFromPendingMap(String sessionId, int id)
+ private class PageSerializingThread implements Runnable
{
- List list = (List)pagesToBeSerialized.get(sessionId);
+ private volatile boolean stop = false;
- if (list == null)
- return;
+ private int serializedInThread = 0;
- synchronized (list)
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ public void run()
{
- Iterator iterator = list.iterator();
- while (iterator.hasNext())
+ while (!stop)
{
- SessionPageKey key = (SessionPageKey)iterator.next();
- if (key.sessionId == sessionId && key.id == id)
+ try
{
- iterator.remove();
- }
- }
- }
- // TODO remove from pages to be saved
- removePage(sessionId, id);
- }
+ while (pagesToBeSerialized.size() == 0)
+ {
+ Thread.sleep(2000);
+ if (stop)
+ return;
+ }
+ Iterator it = pagesToBeSerialized.entrySet().iterator();
+ outer : while (it.hasNext())
+ {
+ Map.Entry entry = (Entry)it.next();
+ List sessionList = (List)entry.getValue();
+ while (true)
+ {
+ Page page = null;
+ SessionPageKey key = null;
+ synchronized (sessionList)
+ {
+ if (sessionList.size() != 0)
+ {
+ key = (SessionPageKey)sessionList.get(0);
+ if (key.data instanceof Page)
+ {
+ page = (Page)key.data;
+ key.setObject(SERIALIZING);
+ }
+ else
+ {
+ sessionList.remove(0);
+ System.err.println("shouldn't happen");
+ continue;
+ }
+ }
+ // no key found in the current list.
+ if (key == null)
+ {
+ // the list is removed now!
+ // but it could be that a request add
+ // something to the list now.
+ // thats why a request has to check it
+ // again.
+ pagesToBeSerialized.remove(entry.getKey());
+ continue outer;
+ }
+ }
- private void removePage(String sessionId, int id)
- {
- File sessionDir = new File(getWorkDir(), sessionId);
- if (sessionDir.exists())
- {
- final String filepart = appName + "-page-" + id;
- File[] listFiles = sessionDir.listFiles(new FilenameFilter()
- {
- public boolean accept(File dir, String name)
+ byte[] pageBytes = serializePage(key, page);
+ serializedInThread++;
+ synchronized (sessionList)
+ {
+ key.setObject(pageBytes);
+ sessionList.remove(key);
+ sessionList.notifyAll();
+ }
+ pagesToBeSaved.put(key, key);
+ }
+ }
+ }
+ catch (Exception e)
{
- return name.startsWith(filepart);
+ log.error("Error in page save thread", e);
}
- });
- for (int i = 0; i < listFiles.length; i++)
- {
- listFiles[i].delete();
}
}
- }
-
- /**
- * Returns the working directory for this disk-based PageStore. Override
- * this to configure a different location. The default is
- * javax.servlet.context.tempdir from the servlet context.
- *
- * @return Working directory
- */
- protected File getWorkDir()
- {
- return defaultWorkDir;
- }
-
- /**
- * @param key
- * @param sessionDir
- * @return The file pointing to the page
- */
- private File getPageFile(SessionPageKey key, File sessionDir)
- {
- return new File(sessionDir, appName + "-pm-" + key.pageMap + "-p-" + key.id + "-v-"
- + key.versionNumber + "-a-" + key.ajaxVersionNumber);
- }
-
- private byte[] serializePage(SessionPageKey key, Page page)
- {
- long t1 = System.currentTimeMillis();
- byte[] bytes = Objects.objectToByteArray(page);
- totalSerializationTime += (System.currentTimeMillis() - t1);
- serialized++;
- if (log.isDebugEnabled())
+ /**
+ * Stops this thread.
+ */
+ public void stop()
{
- log.debug("serializing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
- + "] size: " + bytes.length + " for session " + key.sessionId + " took "
- + (System.currentTimeMillis() - t1) + " miliseconds to serialize");
+ if (log.isDebugEnabled())
+ {
+ log.debug("Total time in serialization: " + totalSerializationTime);
+ log.debug("Total Pages serialized: " + serialized);
+ log.debug("Pages serialized by thread: " + serializedInThread);
+ }
+ stop = true;
}
- return bytes;
}
/**
@@ -436,12 +282,6 @@
private volatile Object data;
- SessionPageKey(String sessionId, Page page)
- {
- this(sessionId, page.getNumericId(), page.getCurrentVersionNumber(), page
- .getAjaxVersionNumber(), page.getPageMap().getName(), page.getClass(), page);
- }
-
SessionPageKey(String sessionId, int id, int versionNumber, int ajaxVersionNumber,
String pagemap, Class pageClass)
{
@@ -460,23 +300,35 @@
this.data = page;
}
+ SessionPageKey(String sessionId, Page page)
+ {
+ this(sessionId, page.getNumericId(), page.getCurrentVersionNumber(), page
+ .getAjaxVersionNumber(), page.getPageMap().getName(), page.getClass(), page);
+ }
+
/**
- * @return The current object inside the SessionPageKey
+ * @see java.lang.Object#equals(java.lang.Object)
*/
- public Object getObject()
+ public boolean equals(Object obj)
{
- return data;
+ if (obj instanceof SessionPageKey)
+ {
+ SessionPageKey key = (SessionPageKey)obj;
+ return id == key.id
+ && versionNumber == key.versionNumber
+ && ajaxVersionNumber == key.ajaxVersionNumber
+ && ((pageMap != null && pageMap.equals(key.pageMap)) || (pageMap == null && key.pageMap == null))
+ && sessionId.equals(key.sessionId);
+ }
+ return false;
}
- /**
- * Sets the current object inside the SessionPageKey
- *
- * @param o
- * The object
+ /**
+ * @return The current object inside the SessionPageKey
*/
- public void setObject(Object o)
+ public Object getObject()
{
- data = o;
+ return data;
}
/**
@@ -488,20 +340,14 @@
}
/**
- * @see java.lang.Object#equals(java.lang.Object)
+ * Sets the current object inside the SessionPageKey
+ *
+ * @param o
+ * The object
*/
- public boolean equals(Object obj)
+ public void setObject(Object o)
{
- if (obj instanceof SessionPageKey)
- {
- SessionPageKey key = (SessionPageKey)obj;
- return id == key.id
- && versionNumber == key.versionNumber
- && ajaxVersionNumber == key.ajaxVersionNumber
- && ((pageMap != null && pageMap.equals(key.pageMap)) || (pageMap == null && key.pageMap == null))
- && sessionId.equals(key.sessionId);
- }
- return false;
+ data = o;
}
/**
@@ -514,223 +360,377 @@
}
}
- private class PageSavingThread implements Runnable
+ private static final Object SERIALIZING = new Object();
+ /** log. */
+ protected static Log log = LogFactory.getLog(FilePageStore.class);
+
+
+ private final File defaultWorkDir;
+ private final PageSerializingThread serThread;
+
+
+ private final ConcurrentHashMap pagesToBeSerialized;
+
+ private final PageSavingThread saveThread;
+ private final ConcurrentHashMap pagesToBeSaved;
+
+ private final String appName;
+
+ private volatile int serialized;
+
+ private volatile long totalSerializationTime = 0;
+
+ /**
+ * Construct.
+ */
+ public FilePageStore()
{
- private volatile boolean stop = false;
- private long totalSavingTime = 0;
- private int saved;
- private int bytesSaved;
+ this((File)((WebApplication)Application.get()).getServletContext().getAttribute(
+ "javax.servlet.context.tempdir"));
+ }
- /**
- * Stops this thread.
- */
- public void stop()
+ /**
+ * Construct.
+ *
+ * @param dir
+ * The directory to save to.
+ */
+ public FilePageStore(File dir)
+ {
+ defaultWorkDir = new File(dir, "sessions/");
+ defaultWorkDir.mkdirs();
+
+ pagesToBeSerialized = new ConcurrentHashMap();
+ pagesToBeSaved = new ConcurrentHashMap();
+ appName = Application.get().getApplicationKey();
+
+ saveThread = new PageSavingThread();
+ Thread t = new Thread(saveThread, "FilePageSavingThread-" + appName);
+ t.setDaemon(true);
+ t.setPriority(Thread.MAX_PRIORITY);
+ t.start();
+
+ serThread = new PageSerializingThread();
+ t = new Thread(serThread, "FilePageSerializingThread-" + appName);
+ t.setDaemon(true);
+ t.setPriority(Thread.NORM_PRIORITY);
+ t.start();
+
+ log.info("storing sessions in " + dir + "/sessions");
+ }
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#destroy()
+ */
+ public void destroy()
+ {
+ saveThread.stop();
+ serThread.stop();
+ }
+
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#getPage(java.lang.String,
+ * int, int)
+ */
+ public Page getPage(String sessionId, String pagemapName, int id, int versionNumber,
+ int ajaxVersionNumber)
+ {
+ SessionPageKey currentKey = new SessionPageKey(sessionId, id, versionNumber,
+ ajaxVersionNumber, pagemapName, null);
+ long t = System.currentTimeMillis();
+ byte[] bytes = testMap(currentKey);
+ if (bytes != null)
{
- if (log.isDebugEnabled())
- {
- log.debug("Total time in saving: " + totalSavingTime);
- log.debug("Bytes saved: " + bytesSaved);
- log.debug("Pages saved: " + saved);
- }
- stop = true;
+ Page page = (Page)Objects.byteArrayToObject(bytes);
+ page = page.getVersion(versionNumber);
+ return page;
}
-
- /**
- * @see java.lang.Runnable#run()
- */
- public void run()
+ File sessionDir = new File(getWorkDir(), sessionId);
+ if (sessionDir.exists())
{
- while (!stop)
+ File pageFile = getPageFile(currentKey, sessionDir);
+ if (pageFile.exists())
{
+ long t1 = System.currentTimeMillis();
+ FileInputStream fis = null;
try
{
- while (pagesToBeSaved.size() == 0)
+ byte[] pageData = null;
+ fis = new FileInputStream(pageFile);
+ int length = (int)pageFile.length();
+ ByteBuffer bb = ByteBuffer.allocate(length);
+ fis.getChannel().read(bb);
+ if (bb.hasArray())
{
- Thread.sleep(2000);
- if (stop)
- return;
+ pageData = bb.array();
}
- // if ( pagesToBeSaved.size() > 100)
- // {
- // System.err.println("max");
- // Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
- // }
- // else if ( pagesToBeSaved.size() > 25)
- // {
- // System.err.println("normal");
- // Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
- // }
- // else
- // {
- // System.err.println("min");
- // Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
- // }
- Iterator it = pagesToBeSaved.entrySet().iterator();
- while (it.hasNext())
+ else
{
- Map.Entry entry = (Entry)it.next();
- SessionPageKey key = (SessionPageKey)entry.getKey();
- if (key.data instanceof byte[])
+ pageData = new byte[length];
+ bb.get(pageData);
+ }
+ long t2 = System.currentTimeMillis();
+ Page page = (Page)Objects.byteArrayToObject(pageData);
+ page = page.getVersion(versionNumber);
+ if (page != null && log.isDebugEnabled())
+ {
+ long t3 = System.currentTimeMillis();
+ log.debug("restoring page " + page.getClass() + "[" + page.getNumericId()
+ + "," + page.getCurrentVersionNumber() + "] size: "
+ + pageData.length + " for session " + sessionId + " took "
+ + (t2 - t1) + " miliseconds to read in and " + (t3 - t2)
+ + " miliseconds to deserialize");
+ }
+ return page;
+ }
+ catch (Exception e)
+ {
+ log.debug("Error loading page " + id + "," + versionNumber
+ + " for the sessionid " + sessionId + " from disk", e);
+ }
+ finally
+ {
+ try
+ {
+ if (fis != null)
{
- savePage(key, (byte[])key.data);
+ fis.close();
}
- it.remove();
+ }
+ catch (IOException ex)
+ {
+ // ignore
}
}
- catch (Exception e)
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#pageAccessed(java.lang.String,
+ * wicket.Page)
+ */
+ public void pageAccessed(String sessionId, Page page)
+ {
+ SessionPageKey currentKey = new SessionPageKey(sessionId, page);
+ testMap(currentKey);
+ }
+
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#removePage(java.lang.String,
+ * wicket.Page)
+ */
+ public void removePage(String sessionId, Page page)
+ {
+ removePageFromPendingMap(sessionId, page.getNumericId());
+ }
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#storePage(java.lang.String,
+ * wicket.Page)
+ */
+ public void storePage(String sessionId, Page page)
+ {
+ List list = (List)pagesToBeSerialized.get(sessionId);
+ if (list == null)
+ {
+ list = new LinkedList();
+ }
+ synchronized (list)
+ {
+ list.add(new SessionPageKey(sessionId, page));
+ }
+ // do really put it back in.. The writer thread could have removed it.
+ pagesToBeSerialized.put(sessionId, list);
+ }
+
+ /**
+ * @see wicket.protocol.http.SecondLevelCacheSessionStore.IPageStore#unbind(java.lang.String)
+ */
+ public void unbind(String sessionId)
+ {
+ removeSessionFromPendingMap(sessionId);
+ }
+
+ /**
+ * @param key
+ * @param sessionDir
+ * @return The file pointing to the page
+ */
+ private File getPageFile(SessionPageKey key, File sessionDir)
+ {
+ return new File(sessionDir, appName + "-pm-" + key.pageMap + "-p-" + key.id + "-v-"
+ + key.versionNumber + "-a-" + key.ajaxVersionNumber);
+ }
+
+
+ private void removePage(String sessionId, int id)
+ {
+ File sessionDir = new File(getWorkDir(), sessionId);
+ if (sessionDir.exists())
+ {
+ final String filepart = appName + "-page-" + id;
+ File[] listFiles = sessionDir.listFiles(new FilenameFilter()
+ {
+ public boolean accept(File dir, String name)
{
- log.error("Error in page save thread", e);
+ return name.startsWith(filepart);
}
+ });
+ for (int i = 0; i < listFiles.length; i++)
+ {
+ listFiles[i].delete();
}
}
+ }
- /**
- * @param sessionId
- * @param key
- * @param bytes
- */
- private void savePage(SessionPageKey key, byte[] bytes)
- {
- File sessionDir = new File(getWorkDir(), key.sessionId);
- sessionDir.mkdirs();
- File pageFile = getPageFile(key, sessionDir);
+ /**
+ * @param sessionId
+ * @param id
+ */
+ private void removePageFromPendingMap(String sessionId, int id)
+ {
+ List list = (List)pagesToBeSerialized.get(sessionId);
- FileOutputStream fos = null;
- long t1 = System.currentTimeMillis();
- int length = 0;
- try
- {
- fos = new FileOutputStream(pageFile);
- ByteBuffer bb = ByteBuffer.wrap(bytes);
- fos.getChannel().write(bb);
- length = bytes.length;
- }
- catch (Exception e)
- {
- log.error("Error saving page " + key.pageClass + " [" + key.id + ","
- + key.versionNumber + "] for the sessionid " + key.sessionId);
- }
- finally
+ if (list == null)
+ return;
+
+ synchronized (list)
+ {
+ Iterator iterator = list.iterator();
+ while (iterator.hasNext())
{
- try
+ SessionPageKey key = (SessionPageKey)iterator.next();
+ if (key.sessionId == sessionId && key.id == id)
{
- if (fos != null)
- {
- fos.close();
- }
+ iterator.remove();
}
- catch (IOException ex)
+ }
+ }
+ // TODO remove from pages to be saved
+ removePage(sessionId, id);
+ }
+
+ private void removeSession(String sessionId)
+ {
+ File sessionDir = new File(getWorkDir(), sessionId);
+ if (sessionDir.exists())
+ {
+ File[] files = sessionDir.listFiles();
+ if (files != null)
+ {
+ for (int i = 0; i < files.length; i++)
{
- // ignore
+ files[i].delete();
}
}
- long t3 = System.currentTimeMillis();
- if (log.isDebugEnabled())
+ if (!sessionDir.delete())
{
- log.debug("storing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
- + "] size: " + length + " for session " + key.sessionId + " took "
- + (t3 - t1) + " miliseconds to save");
+ sessionDir.deleteOnExit();
}
- totalSavingTime += (t3 - t1);
- saved++;
- bytesSaved += length;
}
-
}
- private class PageSerializingThread implements Runnable
+ private void removeSessionFromPendingMap(String sessionId)
{
- private volatile boolean stop = false;
+ pagesToBeSerialized.remove(sessionId);
+ // TODO remove from pagesToBeSaved..
+ removeSession(sessionId);
- private int serializedInThread = 0;
+ }
- /**
- * Stops this thread.
- */
- public void stop()
+ private byte[] serializePage(SessionPageKey key, Page page)
+ {
+ long t1 = System.currentTimeMillis();
+ byte[] bytes = Objects.objectToByteArray(page);
+ totalSerializationTime += (System.currentTimeMillis() - t1);
+ serialized++;
+ if (log.isDebugEnabled())
{
- if (log.isDebugEnabled())
- {
- log.debug("Total time in serialization: " + totalSerializationTime);
- log.debug("Total Pages serialized: " + serialized);
- log.debug("Pages serialized by thread: " + serializedInThread);
- }
- stop = true;
+ log.debug("serializing page " + key.pageClass + "[" + key.id + "," + key.versionNumber
+ + "] size: " + bytes.length + " for session " + key.sessionId + " took "
+ + (System.currentTimeMillis() - t1) + " miliseconds to serialize");
}
+ return bytes;
+ }
- /**
- * @see java.lang.Runnable#run()
- */
- public void run()
+ private byte[] testMap(SessionPageKey currentKey)
+ {
+ SessionPageKey previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
+ if (previousPage != null)
{
- while (!stop)
+ return (byte[])previousPage.data;
+ }
+ List list = (List)pagesToBeSerialized.get(currentKey.sessionId);
+
+ if (list == null)
+ return null;
+
+ synchronized (list)
+ {
+ int index = list.indexOf(currentKey);
+ if (index != -1)
{
- try
+ currentKey = (SessionPageKey)list.get(index);
+ Object object = currentKey.data;
+ if (object instanceof Page)
{
- while (pagesToBeSerialized.size() == 0)
+ list.remove(index);
+ }
+ else if (object == SERIALIZING)
+ {
+ try
{
- Thread.sleep(2000);
- if (stop)
- return;
+ list.wait();
}
-
- Iterator it = pagesToBeSerialized.entrySet().iterator();
- outer : while (it.hasNext())
+ catch (InterruptedException ex)
{
- Map.Entry entry = (Entry)it.next();
- List sessionList = (List)entry.getValue();
- while (true)
+ throw new RuntimeException(ex);
+ }
+ object = currentKey.data;
+ if (object instanceof byte[])
+ {
+ return (byte[])object;
+ }
+ else
+ {
+ previousPage = (SessionPageKey)pagesToBeSaved.get(currentKey);
+ if (previousPage != null)
{
- Page page = null;
- SessionPageKey key = null;
- synchronized (sessionList)
- {
- if (sessionList.size() != 0)
- {
- key = (SessionPageKey)sessionList.get(0);
- if (key.data instanceof Page)
- {
- page = (Page)key.data;
- key.setObject(SERIALIZING);
- }
- else
- {
- sessionList.remove(0);
- System.err.println("shouldn't happen");
- continue;
- }
- }
- // no key found in the current list.
- if (key == null)
- {
- // the list is removed now!
- // but it could be that a request add
- // something to the list now.
- // thats why a request has to check it
- // again.
- pagesToBeSerialized.remove(entry.getKey());
- continue outer;
- }
- }
-
- byte[] pageBytes = serializePage(key, page);
- serializedInThread++;
- synchronized (sessionList)
- {
- key.setObject(pageBytes);
- sessionList.remove(key);
- sessionList.notifyAll();
- }
- pagesToBeSaved.put(key, key);
+ return (byte[])previousPage.data;
}
+ return null;
}
}
- catch (Exception e)
- {
- log.error("Error in page save thread", e);
- }
}
+ else
+ {
+ return null;
+ }
+ }
+
+ byte[] bytes = serializePage(currentKey, (Page)currentKey.data);
+ if (bytes != null)
+ {
+ currentKey.setObject(bytes);
+ pagesToBeSaved.put(currentKey, currentKey);
}
+ return bytes;
+ }
+
+ /**
+ * Returns the working directory for this disk-based PageStore. Override
+ * this to configure a different location. The default is
+ * javax.servlet.context.tempdir from the servlet context.
+ *
+ * @return Working directory
+ */
+ protected File getWorkDir()
+ {
+ return defaultWorkDir;
}
}