Example #1
0
        private CriticalSectionState GetCriticalSectionState(int taskDefinitionId, CriticalSectionType criticalSectionType, SqlCommand command)
        {
            command.Parameters.Clear();
            if (criticalSectionType == CriticalSectionType.User)
            {
                command.CommandText = TokensQueryBuilder.GetUserCriticalSectionStateQuery;
            }
            else
            {
                command.CommandText = TokensQueryBuilder.GetClientCriticalSectionStateQuery;
            }

            command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinitionId;

            using (var reader = command.ExecuteReader())
            {
                var readSuccess = reader.Read();
                if (readSuccess)
                {
                    var csState = new CriticalSectionState();
                    csState.IsGranted          = int.Parse(reader[GetCsStatusColumnName(criticalSectionType)].ToString()) == 0;
                    csState.GrantedToExecution = reader[GetGrantedToColumnName(criticalSectionType)].ToString();
                    csState.SetQueue(reader[GetQueueColumnName(criticalSectionType)].ToString());
                    csState.StartTrackingModifications();

                    return(csState);
                }
            }

            throw new CriticalSectionException("No Task exists with id " + taskDefinitionId);
        }
 public StartCriticalSectionRequest(TaskId taskId,
     string taskExecutionId,
     TaskDeathMode taskDeathMode,
     CriticalSectionType criticalSectionType)
     : base(taskId, taskExecutionId)
 {
     TaskDeathMode = taskDeathMode;
     Type = criticalSectionType;
 }
        private string GetQueueColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
            {
                return("UserCsQueue");
            }

            return("ClientCsQueue");
        }
        private string GetCsStatusColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
            {
                return("UserCsStatus");
            }

            return("ClientCsStatus");
        }
        private string GetGrantedToColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
            {
                return("UserCsTaskExecutionId");
            }

            return("ClientCsTaskExecutionId");
        }
 public StartCriticalSectionRequest(TaskId taskId,
                                    string taskExecutionId,
                                    TaskDeathMode taskDeathMode,
                                    CriticalSectionType criticalSectionType)
     : base(taskId, taskExecutionId)
 {
     TaskDeathMode = taskDeathMode;
     Type          = criticalSectionType;
 }
Example #7
0
        public CriticalSectionContext(ICriticalSectionRepository criticalSectionRepository,
                                      TaskExecutionInstance taskExecutionInstance,
                                      TaskExecutionOptions taskExecutionOptions,
                                      CriticalSectionType criticalSectionType)
        {
            _criticalSectionRepository = criticalSectionRepository;
            _taskExecutionInstance     = taskExecutionInstance;
            _taskExecutionOptions      = taskExecutionOptions;
            _criticalSectionType       = criticalSectionType;

            ValidateOptions();
        }
        public CriticalSectionContext(ICriticalSectionRepository criticalSectionRepository,
            TaskExecutionInstance taskExecutionInstance,
            TaskExecutionOptions taskExecutionOptions,
            CriticalSectionType criticalSectionType)
        {
            _criticalSectionRepository = criticalSectionRepository;
            _taskExecutionInstance = taskExecutionInstance;
            _taskExecutionOptions = taskExecutionOptions;
            _criticalSectionType = criticalSectionType;

            ValidateOptions();
        }
        private CompleteCriticalSectionResponse ReturnCriticalSectionToken(TaskId taskId, int taskDefinitionId, string taskExecutionId, CriticalSectionType criticalSectionType)
        {
            var response = new CompleteCriticalSectionResponse();

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

                var command = connection.CreateCommand();
                command.Transaction = transaction;

                if (criticalSectionType == CriticalSectionType.User)
                    command.CommandText = TokensQueryBuilder.ReturnUserCriticalSectionTokenQuery;
                else
                    command.CommandText = TokensQueryBuilder.ReturnClientCriticalSectionTokenQuery;

                command.CommandTimeout = ConnectionStore.Instance.GetConnection(taskId).QueryTimeoutSeconds;
                command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinitionId;
                command.Parameters.Add("@TaskExecutionId", SqlDbType.Int).Value = int.Parse(taskExecutionId);

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

            return response;
        }
        private async Task <CompleteCriticalSectionResponse> ReturnCriticalSectionTokenAsync(TaskId taskId, int taskDefinitionId, string taskExecutionId, CriticalSectionType criticalSectionType)
        {
            var response = new CompleteCriticalSectionResponse();

            using (var connection = await CreateNewConnectionAsync(taskId).ConfigureAwait(false))
            {
                SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);

                var command = connection.CreateCommand();
                command.Transaction = transaction;

                if (criticalSectionType == CriticalSectionType.User)
                {
                    command.CommandText = TokensQueryBuilder.ReturnUserCriticalSectionTokenQuery;
                }
                else
                {
                    command.CommandText = TokensQueryBuilder.ReturnClientCriticalSectionTokenQuery;
                }

                command.CommandTimeout = ConnectionStore.Instance.GetConnection(taskId).QueryTimeoutSeconds;
                command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinitionId;
                command.Parameters.Add("@TaskExecutionId", SqlDbType.Int).Value  = int.Parse(taskExecutionId);

                try
                {
                    await command.ExecuteNonQueryAsync().ConfigureAwait(false);

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

            return(response);
        }
        private async Task UpdateCriticalSectionStateAsync(int taskDefinitionId, CriticalSectionState csState, CriticalSectionType criticalSectionType, SqlCommand command)
        {
            command.Parameters.Clear();

            if (criticalSectionType == CriticalSectionType.User)
            {
                command.CommandText = TokensQueryBuilder.SetUserCriticalSectionStateQuery;
            }
            else
            {
                command.CommandText = TokensQueryBuilder.SetClientCriticalSectionStateQuery;
            }

            command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value  = taskDefinitionId;
            command.Parameters.Add("@CsStatus", SqlDbType.Int).Value          = csState.IsGranted ? 1 : 0;
            command.Parameters.Add("@CsTaskExecutionId", SqlDbType.Int).Value = csState.GrantedToExecution;
            command.Parameters.Add("@CsQueue", SqlDbType.VarChar, 8000).Value = csState.GetQueueString();
            await command.ExecuteNonQueryAsync().ConfigureAwait(false);
        }
        private string GetCsStatusColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
                return "UserCsStatus";

            return "ClientCsStatus";
        }
        private CriticalSectionState GetCriticalSectionState(int taskDefinitionId, CriticalSectionType criticalSectionType, SqlCommand command)
        {
            command.Parameters.Clear();
            if (criticalSectionType == CriticalSectionType.User)
                command.CommandText = TokensQueryBuilder.GetUserCriticalSectionStateQuery;
            else
                command.CommandText = TokensQueryBuilder.GetClientCriticalSectionStateQuery;

            command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinitionId;

            using (var reader = command.ExecuteReader())
            {
                var readSuccess = reader.Read();
                if (readSuccess)
                {
                    var csState = new CriticalSectionState();
                    csState.IsGranted = int.Parse(reader[GetCsStatusColumnName(criticalSectionType)].ToString()) == 0;
                    csState.GrantedToExecution = reader[GetGrantedToColumnName(criticalSectionType)].ToString();
                    csState.SetQueue(reader[GetQueueColumnName(criticalSectionType)].ToString());
                    csState.StartTrackingModifications();

                    return csState;
                }
            }

            throw new CriticalSectionException("No Task exists with id " + taskDefinitionId);
        }
 public CompleteCriticalSectionRequest(TaskId taskId, string taskExecutionId, CriticalSectionType criticalSectionType)
     : base(taskId, taskExecutionId)
 {
     Type = criticalSectionType;
 }
        private bool TryAcquireCriticalSection(TaskId taskId, int taskDefinitionId, string taskExecutionId, CriticalSectionType criticalSectionType)
        {
            bool granted = false;

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

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

                try
                {
                    AcquireRowLock(taskDefinitionId, taskExecutionId, command);
                    var csState = GetCriticalSectionState(taskDefinitionId, criticalSectionType, command);
                    CleanseOfExpiredExecutions(csState, command);

                    if (csState.IsGranted)
                    {
                        // if the critical section is still granted to another execution after cleansing
                        // then we rejected the request. If the execution is not in the queue then we add it
                        if (!csState.ExistsInQueue(taskExecutionId))
                            csState.AddToQueue(taskExecutionId);

                        granted = false;
                    }
                    else
                    {
                        if (csState.GetQueue().Any())
                        {
                            if (csState.GetFirstExecutionIdInQueue() == taskExecutionId)
                            {
                                GrantCriticalSection(csState, taskDefinitionId, taskExecutionId, command);
                                csState.RemoveFirstInQueue();
                                granted = true;
                            }
                            else
                            {
                                // not next in queue so cannot be granted the critical section
                                granted = false;
                            }
                        }
                        else
                        {
                            GrantCriticalSection(csState, taskDefinitionId, taskExecutionId, command);
                            granted = true;
                        }
                    }

                    if (csState.HasBeenModified)
                        UpdateCriticalSectionState(taskDefinitionId, csState, criticalSectionType, command);

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

            return granted;
        }
        private string GetQueueColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
                return "UserCsQueue";

            return "ClientCsQueue";
        }
        private string GetGrantedToColumnName(CriticalSectionType criticalSectionType)
        {
            if (criticalSectionType == CriticalSectionType.User)
                return "UserCsTaskExecutionId";

            return "ClientCsTaskExecutionId";
        }
 public CompleteCriticalSectionRequest(TaskId taskId, string taskExecutionId, CriticalSectionType criticalSectionType)
     : base(taskId, taskExecutionId)
 {
     Type = criticalSectionType;
 }
        private async Task <bool> TryAcquireCriticalSectionAsync(TaskId taskId, int taskDefinitionId, string taskExecutionId, CriticalSectionType criticalSectionType)
        {
            bool granted = false;

            using (var connection = await CreateNewConnectionAsync(taskId).ConfigureAwait(false))
            {
                SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);

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

                try
                {
                    await AcquireRowLockAsync(taskDefinitionId, taskExecutionId, command).ConfigureAwait(false);

                    var csState = await GetCriticalSectionStateAsync(taskDefinitionId, criticalSectionType, command).ConfigureAwait(false);
                    await CleanseOfExpiredExecutionsAsync(csState, command).ConfigureAwait(false);

                    if (csState.IsGranted)
                    {
                        // if the critical section is still granted to another execution after cleansing
                        // then we rejected the request. If the execution is not in the queue then we add it
                        if (!csState.ExistsInQueue(taskExecutionId))
                        {
                            csState.AddToQueue(taskExecutionId);
                        }

                        granted = false;
                    }
                    else
                    {
                        if (csState.GetQueue().Any())
                        {
                            if (csState.GetFirstExecutionIdInQueue() == taskExecutionId)
                            {
                                GrantCriticalSection(csState, taskDefinitionId, taskExecutionId, command);
                                csState.RemoveFirstInQueue();
                                granted = true;
                            }
                            else
                            {
                                // not next in queue so cannot be granted the critical section
                                granted = false;
                            }
                        }
                        else
                        {
                            GrantCriticalSection(csState, taskDefinitionId, taskExecutionId, command);
                            granted = true;
                        }
                    }

                    if (csState.HasBeenModified)
                    {
                        await UpdateCriticalSectionStateAsync(taskDefinitionId, csState, criticalSectionType, command).ConfigureAwait(false);
                    }

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

            return(granted);
        }
        private void UpdateCriticalSectionState(int taskDefinitionId, CriticalSectionState csState, CriticalSectionType criticalSectionType, SqlCommand command)
        {
            command.Parameters.Clear();

            if (criticalSectionType == CriticalSectionType.User)
                command.CommandText = TokensQueryBuilder.SetUserCriticalSectionStateQuery;
            else
                command.CommandText = TokensQueryBuilder.SetClientCriticalSectionStateQuery;

            command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinitionId;
            command.Parameters.Add("@CsStatus", SqlDbType.Int).Value = csState.IsGranted ? 1 : 0;
            command.Parameters.Add("@CsTaskExecutionId", SqlDbType.Int).Value = csState.GrantedToExecution;
            command.Parameters.Add("@CsQueue", SqlDbType.VarChar, 8000).Value = csState.GetQueueString();
            command.ExecuteNonQuery();
        }