public void ReturnExecutionToken(TokenRequest tokenRequest, string executionTokenId)
        {
            using (var connection = CreateNewConnection(tokenRequest.TaskId))
            {
                SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);

                var command = connection.CreateCommand();
                command.Transaction = transaction;
                command.CommandTimeout = ConnectionStore.Instance.GetConnection(tokenRequest.TaskId).QueryTimeoutSeconds;

                try
                {
                    AcquireRowLock(tokenRequest.TaskDefinitionId, tokenRequest.TaskExecutionId, command);
                    var tokens = GetTokens(tokenRequest.TaskDefinitionId, command);
                    SetTokenAsAvailable(tokens, executionTokenId);
                    PersistTokens(tokenRequest.TaskDefinitionId, tokens, command);

                    transaction.Commit();
                }
                catch (SqlException sqlEx)
                {
                    TryRollBack(transaction, sqlEx);
                }
                catch (Exception ex)
                {
                    TryRollback(transaction, ex);
                }
            }
        }
        public TokenResponse TryAcquireExecutionToken(TokenRequest tokenRequest)
        {
            var response = new TokenResponse();
            response.StartedAt = DateTime.UtcNow;

            using (var connection = CreateNewConnection(tokenRequest.TaskId))
            {
                SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);

                var command = connection.CreateCommand();
                command.Transaction = transaction;
                command.CommandTimeout = ConnectionStore.Instance.GetConnection(tokenRequest.TaskId).QueryTimeoutSeconds;

                try
                {
                    AcquireRowLock(tokenRequest.TaskDefinitionId, tokenRequest.TaskExecutionId, command);
                    var tokens = GetTokens(tokenRequest.TaskDefinitionId, command);
                    var adjusted = AdjustTokenCount(tokens, tokenRequest.ConcurrencyLimit);
                    var assignableToken = GetAssignableToken(tokens, command);
                    if (assignableToken == null)
                    {
                        response.GrantStatus = GrantStatus.Denied;
                        response.ExecutionTokenId = "0";
                    }
                    else
                    {
                        AssignToken(assignableToken, tokenRequest.TaskExecutionId);
                        response.GrantStatus = GrantStatus.Granted;
                        response.ExecutionTokenId = assignableToken.TokenId;
                        adjusted = true;
                    }

                    if (adjusted)
                        PersistTokens(tokenRequest.TaskDefinitionId, tokens, command);

                    transaction.Commit();
                }
                catch (SqlException sqlEx)
                {
                    TryRollBack(transaction, sqlEx);
                }
                catch (Exception ex)
                {
                    TryRollback(transaction, ex);
                }
            }

            return response;
        }
        private TaskExecutionCompleteResponse ReturnExecutionToken(TaskExecutionCompleteRequest taskExecutionCompleteRequest)
        {
            var taskDefinition = _taskRepository.EnsureTaskDefinition(taskExecutionCompleteRequest.TaskId);

            var tokenRequest = new TokenRequest()
            {
                TaskId = taskExecutionCompleteRequest.TaskId,
                TaskDefinitionId = taskDefinition.TaskDefinitionId,
                TaskExecutionId = taskExecutionCompleteRequest.TaskExecutionId
            };

            _executionTokenRepository.ReturnExecutionToken(tokenRequest, taskExecutionCompleteRequest.ExecutionTokenId);

            var response = new TaskExecutionCompleteResponse();
            response.CompletedAt = DateTime.UtcNow;
            return response;
        }
        private TaskExecutionStartResponse TryGetExecutionToken(TaskId taskId, int taskDefinitionId, int taskExecutionId, int concurrencyLimit)
        {
            var tokenRequest = new TokenRequest()
            {
                TaskId = taskId,
                TaskDefinitionId = taskDefinitionId,
                TaskExecutionId = taskExecutionId.ToString(),
                ConcurrencyLimit = concurrencyLimit
            };

            var tokenResponse = _executionTokenRepository.TryAcquireExecutionToken(tokenRequest);

            var response = new TaskExecutionStartResponse();
            response.ExecutionTokenId = tokenResponse.ExecutionTokenId;
            response.GrantStatus = tokenResponse.GrantStatus;
            response.StartedAt = tokenResponse.StartedAt;
            response.TaskExecutionId = taskExecutionId.ToString();

            return response;
        }