public TaskExecutionInfo ProcessTaskDefinition(SingleTaskDefinition taskDefinition) { var lockInfo = LockInfo.Empty(taskDefinition.Identifier); var taskTypeInfo = _taskManager.GetTaskInfo(taskDefinition.Identifier); //links this task's cancellation token to the manager's token var ctSource = CancellationTokenSource.CreateLinkedTokenSource(_listenerCtSource.Token); try { //Inter-process lock. Ignores the task if it doesn't acquire lock if (taskTypeInfo == null || !_taskManager.LockManager.TryRenewLock(lockInfo, taskTypeInfo.LockCycle, retryLock: true)) { return(new TaskExecutionInfo(_managedThreadPool.CreateCompletedTask(), ctSource, lockInfo, taskDefinition)); } var executionInfoLocal = new TaskExecutionInfo(null, ctSource, lockInfo, taskDefinition); var taskBody = CreateTaskBody(executionInfoLocal, taskTypeInfo); var task = _managedThreadPool.QueueUserWorkItem((o) => taskBody(), null); executionInfoLocal.SetTask(task); return(executionInfoLocal); } catch (Exception ex) { ex.LogException(); return(new TaskExecutionInfo(_managedThreadPool.CreateCompletedTask(), ctSource, lockInfo, taskDefinition)); } }
private async Task <LockInfo> WaitForLockImpl(Guid resource, TimeSpan?lockTimeout, CancellationToken cancellationToken) { LockInfo acquiredLock = LockInfo.Empty(resource); while (!cancellationToken.IsCancellationRequested) { acquiredLock = await TryLockAsync(resource, lockTimeout); if (acquiredLock.AsImmutable().HasLock()) { break; } try { await Task.Delay(1000, cancellationToken); } catch (OperationCanceledException ex) { break; } } return(acquiredLock); }
private async Task <LockInfo> acquireLockAsync(IDbConnectionAsync conn, Guid resource, int lockReference, TimeSpan timeout) { var lockInfo = LockInfo.Empty(resource); var newLockRef = Math.Max(1, lockReference + 1); //only acquires lock if old lock reference number matches, and not locked yet. using (var command = await DbAccessHelperAsync.CreateDbCommand(conn, ACQUIRE_lOCK_COMMANDS)) { command.Parameters.Add(new SqlParameter("newLockRef", newLockRef)); command.Parameters.Add(new SqlParameter("timeout", Convert.ToInt64(timeout.TotalMilliseconds))); command.Parameters.Add(new SqlParameter("lockedByMachine", _machineName)); command.Parameters.Add(new SqlParameter("lockedByPID", _PID)); command.Parameters.Add(new SqlParameter("resource", resource)); command.Parameters.Add(new SqlParameter("lockReference", lockReference)); try { var dbLockedTill = (DateTime?)await command.ExecuteScalarAsync(); if (dbLockedTill != null) { var clock = _clockProvider.GetClock(); lockInfo.Update(dbLockedTill, timeout, newLockRef, clock); } } catch (Exception ex) { ex.LogException(); } return(lockInfo); } }
public async Task <LockInfo> TryLockAsync(Guid resource, TimeSpan?lockTimeout) { EnsureNotDisposed(); lockTimeout = lockTimeout ?? defaultTimeout; verifyTimeoutLimits(lockTimeout.Value); using (var tr = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) using (var conn = CreateConnection()) { var lockReference = await GetFreeReferenceOrNewAsync(conn, resource); //failed to insert record or resource already locked if (lockReference == null) { return(LockInfo.Empty(resource)); } //tries to acquire lock return(await acquireLockAsync(conn, resource, lockReference.Value, lockTimeout.Value)); } }