use of de.invesdwin.util.concurrent.lock.readwrite.IReadWriteLock in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method maybeInitSegment.
public boolean maybeInitSegment(final SegmentedKey<K> segmentedKey, final Function<SegmentedKey<K>, ICloseableIterable<? extends V>> source) {
if (!assertValidSegment(segmentedKey)) {
return false;
}
// 1. check segment status in series storage
final IReadWriteLock segmentTableLock = segmentedTable.getTableLock(segmentedKey);
/*
* We need this synchronized block so that we don't collide on the write lock not being possible to be acquired
* after 1 minute. The ReadWriteLock object should be safe to lock via synchronized keyword since no internal
* synchronization occurs on that object itself
*/
synchronized (segmentTableLock) {
final SegmentStatus status = getSegmentStatusWithReadLock(segmentedKey, segmentTableLock);
// 2. if not existing or false, set status to false -> start segment update -> after update set status to true
if (status == null || status == SegmentStatus.INITIALIZING) {
final ILock segmentWriteLock = segmentTableLock.writeLock();
try {
if (!segmentWriteLock.tryLock(1, TimeUnit.MINUTES)) {
/*
* should not happen here because segment should not yet exist. Though if it happens we would
* rather like an exception instead of a deadlock!
*/
throw Locks.getLockTrace().handleLockException(segmentWriteLock.getName(), new RetryLaterRuntimeException("Write lock could not be acquired for table [" + segmentedTable.getName() + "] and key [" + segmentedKey + "]. Please ensure all iterators are closed!"));
}
} catch (final InterruptedException e1) {
throw new RuntimeException(e1);
}
try {
// no double checked locking required between read and write lock here because of the outer synchronized block
if (status == SegmentStatus.INITIALIZING) {
// initialization got aborted, retry from a fresh state
segmentedTable.deleteRange(segmentedKey);
storage.getSegmentStatusTable().delete(hashKey, segmentedKey.getSegment());
}
initSegmentWithStatusHandling(segmentedKey, source);
onSegmentCompleted(segmentedKey, readRangeValues(segmentedKey.getSegment().getFrom(), segmentedKey.getSegment().getTo(), DisabledLock.INSTANCE, null));
return true;
} finally {
segmentWriteLock.unlock();
}
}
}
// 3. if true do nothing
return false;
}
Aggregations