public EfDistributedLock(Func <AggregateDbContext> contextFactory, EfDistributedLockRecord record, TimeSpan expiration, Action expirationAction = null) { Guard.ArgumentNotNull(contextFactory, nameof(contextFactory)); Guard.ArgumentNotNull(record, nameof(record)); Guard.ArgumentNotNull(expiration, nameof(expiration)); _action = expirationAction; _contextFactory = contextFactory; Expiry = expiration; ExpirationTime = record.LockDateTime; IsAcquired = record.IsAcquired(); LockName = record.Name; LockId = record.LockId; var extendTime = (expiration.TotalMilliseconds * 0.9).Do(Convert.ToInt32); _timer = new PeriodicAction(ct => ExtendLockAsync(ct), extendTime, null, true); _timer.Start(); }
private async Task <EfDistributedLock> TryAquireLock(string name, TimeSpan expiry, Action expirationAction = null) { _logger.StartAcquireLock(name, expiry); try { using (var context = _dbContextFactory()) { var dlock = await context.DistributedLocks.SingleOrDefaultAsync(l => l.Name == name); if (dlock == null) { dlock = new EfDistributedLockRecord(name, expiry, Guid.NewGuid()); context.DistributedLocks.Add(dlock); dlock.Acquire(expiry); var updated = await context.SaveChangesAsync(); if (updated > 0) { _logger.LockIsAcquired(name, expiry); return(new EfDistributedLock(_dbContextFactory, dlock, expiry, expirationAction)); } } if (!dlock.IsAcquired()) { dlock.Acquire(expiry); var updated = await context.SaveChangesAsync(); if (updated > 0) { _logger.LockIsAcquired(name, expiry); return(new EfDistributedLock(_dbContextFactory, dlock, expiry, expirationAction)); } } } } catch (DbUpdateConcurrencyException ex) { _logger.TraceVerboseEvent($"Distributed Lock {name} was not captured due to concurency exception. Exception Message was : {ex.Message}"); } _logger.LockIsNotAcquired(name, expiry); return(null); }