/// <inheritdoc /> public async Task <LockResult> LockAsync(ILock l, CancellationToken cancellationToken) { ActiveLock newActiveLock; var destinationUrl = BuildUrl(l.Path); using (var transaction = await BeginTransactionAsync(cancellationToken).ConfigureAwait(false)) { var locks = await transaction.GetActiveLocksAsync(cancellationToken).ConfigureAwait(false); var status = Find(locks, destinationUrl, l.Recursive, true); var conflictingLocks = GetConflictingLocks(status, LockShareMode.Parse(l.ShareMode)); if (conflictingLocks.Count != 0) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation($"Found conflicting locks for {l}: {string.Join(",", conflictingLocks.GetLocks().Select(x => x.ToString()))}"); } return(new LockResult(conflictingLocks)); } newActiveLock = new ActiveLock(l, _rounding.Round(_systemClock.UtcNow), _rounding.Round(l.Timeout)); await transaction.AddAsync(newActiveLock, cancellationToken).ConfigureAwait(false); await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); } OnLockAdded(newActiveLock); _cleanupTask.Add(this, newActiveLock); return(new LockResult(newActiveLock)); }
/// <summary> /// Initializes a new instance of the <see cref="ActiveLock"/> class. /// </summary> /// <param name="l">The lock to create this active lock from</param> /// <param name="issued">The date/time when this lock was issued</param> /// <param name="timeout">Override the timeout from the original lock (to enforce rounding)</param> internal ActiveLock([NotNull] ILock l, DateTime issued, TimeSpan timeout) : this( l.Path, l.Href, l.Recursive, l.GetOwner(), LockAccessType.Parse(l.AccessType), LockShareMode.Parse(l.ShareMode), timeout, issued, null) { }
private static ActiveLock Refresh(IActiveLock activeLock, DateTime lastRefresh, TimeSpan timeout) { return(new ActiveLock( activeLock.Path, activeLock.Href, activeLock.Recursive, activeLock.GetOwner(), LockAccessType.Parse(activeLock.AccessType), LockShareMode.Parse(activeLock.ShareMode), timeout, activeLock.Issued, lastRefresh, activeLock.StateToken)); }
/// <summary> /// Creates an <see cref="XElement"/> for a <see cref="IActiveLock"/> /// </summary> /// <param name="l">The active lock to create the <see cref="XElement"/> for</param> /// <param name="omitOwner">Should the owner be omitted?</param> /// <param name="omitToken">Should the lock state token be omitted?</param> /// <returns>The newly created <see cref="XElement"/> for the active lock</returns> public static XElement ToXElement(this IActiveLock l, bool omitOwner = false, bool omitToken = false) { var timeout = l.Timeout == TimeoutHeader.Infinite ? "Infinite" : $"Second-{l.Timeout.TotalSeconds:F0}"; var depth = l.Recursive ? DepthHeader.Infinity : DepthHeader.Zero; var lockScope = LockShareMode.Parse(l.ShareMode); var lockType = LockAccessType.Parse(l.AccessType); var owner = l.GetOwner(); var result = new XElement( WebDavXml.Dav + "activelock", new XElement( WebDavXml.Dav + "lockscope", new XElement(lockScope.Name)), new XElement( WebDavXml.Dav + "locktype", new XElement(lockType.Name)), new XElement( WebDavXml.Dav + "depth", depth.Value)); if (owner != null && !omitOwner) { result.Add(owner); } result.Add( new XElement( WebDavXml.Dav + "timeout", timeout)); if (!omitToken) { result.Add( new XElement( WebDavXml.Dav + "locktoken", new XElement(WebDavXml.Dav + "href", l.StateToken))); } result.Add( new XElement( WebDavXml.Dav + "lockroot", new XElement(WebDavXml.Dav + "href", l.Href))); return(result); }
private static LockStatus GetConflictingLocks(LockStatus affactingLocks, LockShareMode shareMode) { if (shareMode == LockShareMode.Exclusive) { return(affactingLocks); } return(new LockStatus( affactingLocks .ReferenceLocks .Where(x => LockShareMode.Parse(x.ShareMode) == LockShareMode.Exclusive) .ToList(), affactingLocks .ParentLocks .Where(x => LockShareMode.Parse(x.ShareMode) == LockShareMode.Exclusive) .ToList(), affactingLocks .ChildLocks .Where(x => LockShareMode.Parse(x.ShareMode) == LockShareMode.Exclusive) .ToList())); }