コード例 #1
0
        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));
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        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));
                }
        }