|
From: <mol...@us...> - 2010-10-25 09:58:31
|
Revision: 3118
http://openutils.svn.sourceforge.net/openutils/?rev=3118&view=rev
Author: molaschi
Date: 2010-10-25 09:58:25 +0000 (Mon, 25 Oct 2010)
Log Message:
-----------
improve caching concurrent checks
Modified Paths:
--------------
trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCacheManager.java
trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCachedItem.java
trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filters/CacheFilter.java
trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/LockableCacheContent.java
trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/SynchCacheContentOperations.java
Modified: trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCacheManager.java
===================================================================
--- trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCacheManager.java 2010-10-12 14:02:23 UTC (rev 3117)
+++ trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCacheManager.java 2010-10-25 09:58:25 UTC (rev 3118)
@@ -455,9 +455,7 @@
// wait that every rw operation finished
for (String key : contents.keySet())
{
- contents.get(key).lockToWrite();
- // when i have lock i can remove;
- contents.get(key).releaseLockToWrite();
+ contents.get(key).waitForWritingLock();
}
contents.clear();
Modified: trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCachedItem.java
===================================================================
--- trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCachedItem.java 2010-10-12 14:02:23 UTC (rev 3117)
+++ trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filesystem/FSCachedItem.java 2010-10-25 09:58:25 UTC (rev 3118)
@@ -173,11 +173,14 @@
*/
public ResetableBufferedOutputStream beginWrite() throws IOException
{
- lockToWrite();
- isnew = false;
- File f = new File(filename);
- f.getParentFile().mkdirs();
- return new ResetableBufferedFileOutputStream(f, this);
+ if (lockToWrite())
+ {
+ isnew = false;
+ File f = new File(filename);
+ f.getParentFile().mkdirs();
+ return new ResetableBufferedFileOutputStream(f, this);
+ }
+ return null;
}
/**
@@ -185,63 +188,67 @@
*/
public boolean endWrite(OutputStream outputStream) throws IOException
{
- IOUtils.closeQuietly(outputStream);
-
- File f = ((ResetableBufferedFileOutputStream) outputStream).getFile();
- if (f.exists() && f.length() > 0)
+ try
{
- FileInputStream fis = new FileInputStream(f);
- byte[] gzipControlChars = new byte[2];
- fis.read(gzipControlChars);
- IOUtils.closeQuietly(fis);
+ IOUtils.closeQuietly(outputStream);
- if (isGZipped(gzipControlChars))
+ File f = ((ResetableBufferedFileOutputStream) outputStream).getFile();
+ if (f != null && f.exists() && f.length() > 0)
{
- FileUtils.moveFile(new File(filename), new File(filenameGzip));
- File fgz = new File(filenameGzip);
- f = new File(filename);
- InputStream is = new GZIPInputStream(new FileInputStream(fgz));
- OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
- IOUtils.copyLarge(is, os);
- IOUtils.closeQuietly(is);
- IOUtils.closeQuietly(os);
- }
- else if (gzipable)
- {
- File fgz = new File(filenameGzip);
- OutputStream os = new GZIPOutputStream(new FileOutputStream(fgz));
- InputStream is = new FileInputStream(f);
- IOUtils.copyLarge(is, os);
- IOUtils.closeQuietly(is);
- IOUtils.closeQuietly(os);
- }
+ FileInputStream fis = new FileInputStream(f);
+ byte[] gzipControlChars = new byte[2];
+ fis.read(gzipControlChars);
+ IOUtils.closeQuietly(fis);
- size = new File(filename).length();
- sizeGzip = new File(filenameGzip).length();
+ if (isGZipped(gzipControlChars))
+ {
+ FileUtils.moveFile(new File(filename), new File(filenameGzip));
+ File fgz = new File(filenameGzip);
+ f = new File(filename);
+ InputStream is = new GZIPInputStream(new FileInputStream(fgz));
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
+ IOUtils.copyLarge(is, os);
+ IOUtils.closeQuietly(is);
+ IOUtils.closeQuietly(os);
+ }
+ else if (gzipable)
+ {
+ File fgz = new File(filenameGzip);
+ OutputStream os = new GZIPOutputStream(new FileOutputStream(fgz));
+ InputStream is = new FileInputStream(f);
+ IOUtils.copyLarge(is, os);
+ IOUtils.closeQuietly(is);
+ IOUtils.closeQuietly(os);
+ }
- getCacheHeaders().getHeaders().put("x-server-cached", "true");
+ size = new File(filename).length();
+ sizeGzip = new File(filenameGzip).length();
- OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(filenameHeaders)));
- try
- {
- getCacheHeaders().serialize(os);
+ getCacheHeaders().getHeaders().put("x-server-cached", "true");
+
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(filenameHeaders)));
+ try
+ {
+ getCacheHeaders().serialize(os);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(os);
+ }
+
+ lastModified = System.currentTimeMillis();
+ return true;
}
- finally
- {
- IOUtils.closeQuietly(os);
- }
+ size = 0;
+ sizeGzip = 0;
lastModified = System.currentTimeMillis();
+ return false;
+ }
+ finally
+ {
releaseLockToWrite();
- return true;
}
-
- size = 0;
- sizeGzip = 0;
- lastModified = System.currentTimeMillis();
-
- releaseLockToWrite();
- return false;
}
/**
Modified: trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filters/CacheFilter.java
===================================================================
--- trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filters/CacheFilter.java 2010-10-12 14:02:23 UTC (rev 3117)
+++ trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/filters/CacheFilter.java 2010-10-25 09:58:25 UTC (rev 3118)
@@ -142,9 +142,16 @@
// get cache from manager
CachedItem cacheContent = cacheManager.get(request);
- // if request is cached
- if (!cacheContent.isNew())
+ OutputStream os = null;
+ if (cacheContent.isNew())
{
+ // if someone is writing, returns null
+ os = cacheContent.beginWrite();
+ }
+
+ // if request is cached (not new or cacheContent.beginWrite returns null)
+ if (os == null)
+ {
InputStream cacheContentInputStream = cacheContent.beginRead(acceptGzip);
boolean reset = true;
@@ -196,8 +203,6 @@
}
}
- OutputStream os = cacheContent.beginWrite();
-
this.startProcessing();
// wrap response and start writing
CacheResponseWrapper cacheContentResponse = new CacheResponseWrapper(response, cacheContent, os);
Modified: trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/LockableCacheContent.java
===================================================================
--- trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/LockableCacheContent.java 2010-10-12 14:02:23 UTC (rev 3117)
+++ trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/LockableCacheContent.java 2010-10-25 09:58:25 UTC (rev 3118)
@@ -19,13 +19,17 @@
package net.sourceforge.openutils.mgnlsimplecache.lock;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import net.sourceforge.openutils.mgnlsimplecache.managers.CachedItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* @author Manuel Molaschi
* @author Fabrizio Giustina
@@ -34,6 +38,13 @@
public abstract class LockableCacheContent implements CachedItem
{
+ /**
+ * Logger.
+ */
+ private Logger log = LoggerFactory.getLogger(LockableCacheContent.class);
+
+ private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
private ReadLock readLock;
private WriteLock writeLock;
@@ -43,7 +54,6 @@
*/
public LockableCacheContent()
{
- ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
readLock = lock.readLock();
writeLock = lock.writeLock();
}
@@ -53,11 +63,41 @@
readLock.lock();
}
- public void lockToWrite()
+ public boolean lockToWrite()
{
- writeLock.lock();
+ if (lock.isWriteLockedByCurrentThread())
+ {
+ RuntimeException ex = new RuntimeException("Double call to write lock while caching!!!");
+ ex.fillInStackTrace();
+ log.error("Exception getting lock for writing on cache: ", ex);
+ throw ex;
+ }
+ return writeLock.tryLock();
}
+ public void waitForWritingLock()
+ {
+ if (isWritingLocked())
+ {
+ try
+ {
+ writeLock.tryLock(10, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException e)
+ {
+
+ }
+ finally
+ {
+ int holdCount = lock.getWriteHoldCount();
+ for (int i = 0; i < holdCount; i++)
+ {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+
public void releaseLockToWrite()
{
writeLock.unlock();
@@ -67,4 +107,9 @@
{
readLock.unlock();
}
+
+ public boolean isWritingLocked()
+ {
+ return lock.isWriteLocked();
+ }
}
Modified: trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/SynchCacheContentOperations.java
===================================================================
--- trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/SynchCacheContentOperations.java 2010-10-12 14:02:23 UTC (rev 3117)
+++ trunk/openutils-mgnlcache/src/main/java/net/sourceforge/openutils/mgnlsimplecache/lock/SynchCacheContentOperations.java 2010-10-25 09:58:25 UTC (rev 3118)
@@ -54,7 +54,7 @@
public static <T, S> T doWrite(CachedItem cache, S arguments, SynchedOp<T, S> callback) throws Exception
{
boolean release = false;
- if (cache instanceof LockableCacheContent)
+ if (cache instanceof LockableCacheContent && !((LockableCacheContent) cache).isWritingLocked())
{
((LockableCacheContent) cache).lockToWrite();
release = true;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|