
|
If you were logged in you would be able to see more operations.
|
|
|
OSCache
Created: 06/Jul/05 09:05 AM
Updated: 07/Jul/05 05:09 AM
|
|
| Component/s: |
Filters
|
| Affects Version/s: |
2.1
|
| Fix Version/s: |
2.2 RC
|
|
|
We found a very bad issue which causes the cache to deadlock and completly block access to some resources.
The problem is related to how cache keys are updated,
currently OS-Cache will mark a cache-key as being 'created/updated' and will block all forthcoming requests to that resource until the first request is completed
we however observed the following behaviour:
- Client Thread 1: GET /upload/problem.pdf (which is 200K)
- Client Thread 1: READ 200 Bytes
- OS-Cache Thread 1 (serving Client Thread 1): create cache entry and block resource /upload/problem.pdf
- Client Thread 1: decide that this may be a PDF, spawn Client Thread 2 to try indexing, wait for Thread 2 to complete
- Client Thread 2: GET /upload/problem.pdf
- Client Thread 2: READ 1000 Bytes
- OS-Cache Thread 2 (serving Client Thread 2): wait for OS-Cache Thread 1 to complete
as a result now no one will bne able to access that resource and we'll have lost 2 threads/sockets.
This issue definitively needs to be fixed, owr solution is as follows:
class: com.opensympony.oscache.base.Cache:
/**
* Simone: check if the entry is being updated
*
* @param key
* @return
*/
public boolean isUpdatingEntry(String key) {
EntryUpdateState updateState = getUpdateState(key);
if (updateState==null)
return false;
synchronized (updateState) {
if (updateState.isUpdating())
return true;
else
return false;
}
}
class: Filter:
added the following code before starting to cache /acntuall within the try block):
// avoid blocking when 2 clients
if (cache.isUpdatingEntry(key)) {
// 1: try delaying the request to allow the other thread to complete
try {
Thread.sleep(5000 +(System.currentTimeMillis()%4000) );
} catch (InterruptedException ie) {
// that's ok
}
// 2: is still busy bypass the cache
if (cache.isUpdatingEntry(key)) {
chain.doFilter(request,response);
return;
}
}
|
|
Description
|
We found a very bad issue which causes the cache to deadlock and completly block access to some resources.
The problem is related to how cache keys are updated,
currently OS-Cache will mark a cache-key as being 'created/updated' and will block all forthcoming requests to that resource until the first request is completed
we however observed the following behaviour:
- Client Thread 1: GET /upload/problem.pdf (which is 200K)
- Client Thread 1: READ 200 Bytes
- OS-Cache Thread 1 (serving Client Thread 1): create cache entry and block resource /upload/problem.pdf
- Client Thread 1: decide that this may be a PDF, spawn Client Thread 2 to try indexing, wait for Thread 2 to complete
- Client Thread 2: GET /upload/problem.pdf
- Client Thread 2: READ 1000 Bytes
- OS-Cache Thread 2 (serving Client Thread 2): wait for OS-Cache Thread 1 to complete
as a result now no one will bne able to access that resource and we'll have lost 2 threads/sockets.
This issue definitively needs to be fixed, owr solution is as follows:
class: com.opensympony.oscache.base.Cache:
/**
* Simone: check if the entry is being updated
*
* @param key
* @return
*/
public boolean isUpdatingEntry(String key) {
EntryUpdateState updateState = getUpdateState(key);
if (updateState==null)
return false;
synchronized (updateState) {
if (updateState.isUpdating())
return true;
else
return false;
}
}
class: Filter:
added the following code before starting to cache /acntuall within the try block):
// avoid blocking when 2 clients
if (cache.isUpdatingEntry(key)) {
// 1: try delaying the request to allow the other thread to complete
try {
Thread.sleep(5000 +(System.currentTimeMillis()%4000) );
} catch (InterruptedException ie) {
// that's ok
}
// 2: is still busy bypass the cache
if (cache.isUpdatingEntry(key)) {
chain.doFilter(request,response);
return;
}
}
|
Show » |
|
CACHE-170, hence we can close this issue as a duplicate.