Skip to content

Commit

Permalink
Merge pull request #349 from dice-group/hotfix/348
Browse files Browse the repository at this point in the history
Fixed #348 by ensuring that semaphore permits are released.
  • Loading branch information
MichaelRoeder authored May 1, 2020
2 parents 5f3f330 + 7c986e2 commit af75d65
Showing 1 changed file with 59 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,62 +111,88 @@ public Set<String> retrieveSameURIs(String uri) {
// if the cache contains the uri, return the set or a set
// containing only the uri (use the read mutex!!!)
Set<String> result = null;
boolean uriIsCached = false;
try {
cacheReadMutex.acquire();
} catch (InterruptedException e) {
LOGGER.error("Exception while waiting for read mutex. Returning null.", e);
return null;
}
boolean uriIsCached = uriSetIdMapping.containsKey(uri);
if (uriIsCached) {
int setId = uriSetIdMapping.get(uri);
if (setId != ENTITY_NOT_FOUND) {
result = sets.get(setId);
try {
uriIsCached = uriSetIdMapping.containsKey(uri);
if (uriIsCached) {
int setId = uriSetIdMapping.get(uri);
if (setId != ENTITY_NOT_FOUND) {
result = sets.get(setId);
}
}
} finally {
cacheReadMutex.release();
}
// If the URI is not in the cache, or it has been cached but the result
// is null and the request should be retried
if (!uriIsCached || (uriIsCached && (result == null) && requestEntitiesNotFound)) {
cacheReadMutex.release();
result = decoratedRetriever.retrieveSameURIs(uri);
result = requestUri(uri);
}
return result;
}

/**
* Requests the set for the given URI from the decorated retriever.
*
* @param uri
* @return
*/
protected Set<String> requestUri(String uri) {
Set<String> result = decoratedRetriever.retrieveSameURIs(uri);
try {
cacheWriteMutex.acquire();
} catch (InterruptedException e) {
LOGGER.error("Exception while waiting for read mutex. Returning null.", e);
return null;
}
// Make sure that the write mutex is released
try {
try {
cacheWriteMutex.acquire();
// now we need all others
// now we need all other read mutexes
cacheReadMutex.acquire(MAX_CONCURRENT_READERS);
} catch (InterruptedException e) {
LOGGER.error("Exception while waiting for read mutex. Returning null.", e);
return null;
}
// Check again that nobody already added the uri
if (uriSetIdMapping.containsKey(uri)) {
// use the cached result
int setId = uriSetIdMapping.get(uri);
if (setId != ENTITY_NOT_FOUND) {
result = sets.get(setId);
} else {
result = null;
}
} else {
if (result != null) {
mergeSetIntoCache(result);
// Make sure that the read mutex is released
try {
// Check again that nobody already added the uri
if (uriSetIdMapping.containsKey(uri)) {
// use the cached result
int setId = uriSetIdMapping.get(uri);
if (setId != ENTITY_NOT_FOUND) {
result = sets.get(setId);
} else {
result = null;
}
} else {
uriSetIdMapping.put(uri, ENTITY_NOT_FOUND);
}
++cacheChanges;
if ((forceStorageAfterChanges > 0) && (cacheChanges >= forceStorageAfterChanges)) {
LOGGER.info("Storing the cache has been forced...");
try {
performCacheStorage();
} catch (IOException e) {
LOGGER.error("Exception while writing cache to file. Aborting.", e);
if (result != null) {
mergeSetIntoCache(result);
} else {
uriSetIdMapping.put(uri, ENTITY_NOT_FOUND);
}
++cacheChanges;
if ((forceStorageAfterChanges > 0) && (cacheChanges >= forceStorageAfterChanges)) {
LOGGER.info("Storing the cache has been forced...");
try {
performCacheStorage();
} catch (IOException e) {
LOGGER.error("Exception while writing cache to file. Aborting.", e);
}
}
}
} finally {
cacheReadMutex.release(MAX_CONCURRENT_READERS);
}
// The last one will be released at the end
cacheReadMutex.release(MAX_CONCURRENT_READERS - 1);
} finally {
cacheWriteMutex.release();
}
cacheReadMutex.release();
return result;
}

Expand Down

0 comments on commit af75d65

Please sign in to comment.