/// <summary> /// Stop any other transactions reading or writing this item to/from /// the cache. Send them straight to the database instead. (The lock /// does time out eventually.) This implementation tracks concurrent /// locks by transactions which simultaneously attempt to write to an /// item. /// </summary> public async Task <ISoftLock> LockAsync(CacheKey key, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (await(_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); } var lockValue = await(_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { ILockable lockable = (ILockable)await(Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); long timeout = Cache.NextTimestamp() + Cache.Timeout; CacheLock @lock = lockable == null? CacheLock.Create(timeout, NextLockId(), version) : lockable.Lock(timeout, NextLockId()); await(Cache.PutAsync(key, @lock, cancellationToken)).ConfigureAwait(false); return(@lock); } finally { await(_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } }
/// <summary> /// Stop any other transactions reading or writing this item to/from /// the cache. Send them straight to the database instead. (The lock /// does time out eventually.) This implementation tracks concurrent /// locks by transactions which simultaneously attempt to write to an /// item. /// </summary> public ISoftLock Lock(CacheKey key, object version) { lock (_lockObject) { if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); } try { cache.Lock(key); ILockable lockable = (ILockable)cache.Get(key); long timeout = cache.NextTimestamp() + cache.Timeout; CacheLock @lock = lockable == null? CacheLock.Create(timeout, NextLockId(), version) : lockable.Lock(timeout, NextLockId()); cache.Put(key, @lock); return(@lock); } finally { cache.Unlock(key); } } }
internal void HandleLockExpiry(object key) { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @lock.Unlock(ts); cache.Put(key, @lock); }
internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <object>(cancellationToken)); } try { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); long ts = Cache.NextTimestamp() + Cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @lock.Unlock(ts); return(Cache.PutAsync(key, @lock, cancellationToken)); } catch (System.Exception ex) { return(Task.FromException <object>(ex)); } }