Search in sources :

Example 1 with IReadWriteLock

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;
}
Also used : RetryLaterRuntimeException(de.invesdwin.context.integration.retry.RetryLaterRuntimeException) RetryLaterRuntimeException(de.invesdwin.context.integration.retry.RetryLaterRuntimeException) IReadWriteLock(de.invesdwin.util.concurrent.lock.readwrite.IReadWriteLock) ILock(de.invesdwin.util.concurrent.lock.ILock)

Aggregations

RetryLaterRuntimeException (de.invesdwin.context.integration.retry.RetryLaterRuntimeException)1 ILock (de.invesdwin.util.concurrent.lock.ILock)1 IReadWriteLock (de.invesdwin.util.concurrent.lock.readwrite.IReadWriteLock)1