private async Task ChangeStatusOfNumericRangeExecutionAsync(BlockExecutionChangeStatusRequest changeStatusRequest)
        {
            try
            {
                using (var connection = await CreateNewConnectionAsync(changeStatusRequest.TaskId).ConfigureAwait(false))
                {
                    var command = connection.CreateCommand();
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(changeStatusRequest.TaskId).QueryTimeoutSeconds;
                    command.CommandText    = GetNumericRangeUpdateQuery(changeStatusRequest.BlockExecutionStatus);
                    command.Parameters.Add("@BlockExecutionId", SqlDbType.BigInt).Value      = long.Parse(changeStatusRequest.BlockExecutionId);
                    command.Parameters.Add("@BlockExecutionStatus", SqlDbType.TinyInt).Value = (byte)changeStatusRequest.BlockExecutionStatus;
                    command.Parameters.Add("@ItemsCount", SqlDbType.Int).Value = changeStatusRequest.ItemsProcessed;
                    await command.ExecuteNonQueryAsync().ConfigureAwait(false);
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }
        }
Example #2
0
        public async Task UpdateListBlockItemAsync(SingleUpdateRequest singeUpdateRequest)
        {
            try
            {
                using (var connection = await CreateNewConnectionAsync(singeUpdateRequest.TaskId).ConfigureAwait(false))
                {
                    var command = connection.CreateCommand();
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(singeUpdateRequest.TaskId).QueryTimeoutSeconds;
                    command.CommandText    = ListBlockQueryBuilder.UpdateSingleBlockListItemStatus;
                    command.Parameters.Add("@BlockId", SqlDbType.BigInt).Value         = long.Parse(singeUpdateRequest.ListBlockId);
                    command.Parameters.Add("@ListBlockItemId", SqlDbType.BigInt).Value = long.Parse(singeUpdateRequest.ListBlockItem.ListBlockItemId);
                    command.Parameters.Add("@Status", SqlDbType.TinyInt).Value         = (byte)singeUpdateRequest.ListBlockItem.Status;

                    if (singeUpdateRequest.ListBlockItem.StatusReason == null)
                    {
                        command.Parameters.Add("@StatusReason", SqlDbType.NVarChar, -1).Value = DBNull.Value;
                    }
                    else
                    {
                        command.Parameters.Add("@StatusReason", SqlDbType.NVarChar, -1).Value = singeUpdateRequest.ListBlockItem.StatusReason;
                    }

                    if (!singeUpdateRequest.ListBlockItem.Step.HasValue)
                    {
                        command.Parameters.Add("@Step", SqlDbType.TinyInt).Value = DBNull.Value;
                    }
                    else
                    {
                        command.Parameters.Add("@Step", SqlDbType.TinyInt).Value = singeUpdateRequest.ListBlockItem.Step;
                    }

                    await command.ExecuteNonQueryAsync().ConfigureAwait(false);
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }
        }
Example #3
0
        public ObjectBlock <T> GetLastObjectBlock <T>(LastBlockRequest lastRangeBlockRequest)
        {
            var taskDefinition = _taskRepository.EnsureTaskDefinition(lastRangeBlockRequest.TaskId);

            try
            {
                using (var connection = CreateNewConnection(lastRangeBlockRequest.TaskId))
                {
                    var command = connection.CreateCommand();
                    command.CommandText    = ObjectBlockQueryBuilder.GetLastObjectBlock;
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(lastRangeBlockRequest.TaskId).QueryTimeoutSeconds;
                    command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinition.TaskDefinitionId;
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var blockId       = reader["BlockId"].ToString();
                            var objectDataXml = reader["ObjectData"].ToString();
                            T   objectData    = SerializedValueReader.ReadValue <T>(reader, "ObjectData", "CompressedObjectData");

                            return(new ObjectBlock <T>()
                            {
                                Object = objectData,
                                ObjectBlockId = blockId
                            });
                        }
                    }
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }

            return(null);
        }
Example #4
0
        public async Task <ProtoListBlock> GetLastListBlockAsync(LastBlockRequest lastRangeBlockRequest)
        {
            var taskDefinition = await _taskRepository.EnsureTaskDefinitionAsync(lastRangeBlockRequest.TaskId).ConfigureAwait(false);

            try
            {
                using (var connection = await CreateNewConnectionAsync(lastRangeBlockRequest.TaskId).ConfigureAwait(false))
                {
                    var command = connection.CreateCommand();
                    command.CommandText    = ListBlockQueryBuilder.GetLastListBlock;
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(lastRangeBlockRequest.TaskId).QueryTimeoutSeconds;
                    command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinition.TaskDefinitionId;
                    using (var reader = await command.ExecuteReaderAsync().ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync().ConfigureAwait(false))
                        {
                            var listBlock = new ProtoListBlock();
                            listBlock.ListBlockId = reader["BlockId"].ToString();
                            listBlock.Items       = await GetListBlockItemsAsync(lastRangeBlockRequest.TaskId, listBlock.ListBlockId).ConfigureAwait(false);

                            listBlock.Header = SerializedValueReader.ReadValueAsString(reader, "ObjectData", "CompressedObjectData");

                            return(listBlock);
                        }
                    }
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }

            return(null);
        }
        public void ChangeStatus(BlockExecutionChangeStatusRequest changeStatusRequest)
        {
            try
            {
                using (var connection = CreateNewConnection(changeStatusRequest.TaskId))
                {
                    var command = connection.CreateCommand();
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(changeStatusRequest.TaskId).QueryTimeoutSeconds;
                    command.CommandText    = GetListUpdateQuery(changeStatusRequest.BlockExecutionStatus);
                    command.Parameters.Add("@BlockExecutionId", SqlDbType.BigInt).Value      = long.Parse(changeStatusRequest.BlockExecutionId);
                    command.Parameters.Add("@BlockExecutionStatus", SqlDbType.TinyInt).Value = (byte)changeStatusRequest.BlockExecutionStatus;
                    command.ExecuteNonQuery();
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }
        }
        public async Task <RangeBlock> GetLastRangeBlockAsync(LastBlockRequest lastRangeBlockRequest)
        {
            var taskDefinition = await _taskRepository.EnsureTaskDefinitionAsync(lastRangeBlockRequest.TaskId).ConfigureAwait(false);

            var query = string.Empty;

            if (lastRangeBlockRequest.BlockType == BlockType.DateRange)
            {
                query = RangeBlockQueryBuilder.GetLastDateRangeBlock(lastRangeBlockRequest.LastBlockOrder);
            }
            else if (lastRangeBlockRequest.BlockType == BlockType.NumericRange)
            {
                query = RangeBlockQueryBuilder.GetLastNumericRangeBlock(lastRangeBlockRequest.LastBlockOrder);
            }
            else
            {
                throw new ArgumentException("An invalid BlockType was supplied: " + lastRangeBlockRequest.BlockType);
            }

            try
            {
                using (var connection = await CreateNewConnectionAsync(lastRangeBlockRequest.TaskId).ConfigureAwait(false))
                {
                    var command = connection.CreateCommand();
                    command.CommandText    = query;
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(lastRangeBlockRequest.TaskId).QueryTimeoutSeconds;
                    command.Parameters.Add("@TaskDefinitionId", SqlDbType.Int).Value = taskDefinition.TaskDefinitionId;
                    using (var reader = await command.ExecuteReaderAsync().ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync().ConfigureAwait(false))
                        {
                            var  rangeBlockId = reader["BlockId"].ToString();
                            long rangeBegin;
                            long rangeEnd;

                            if (lastRangeBlockRequest.BlockType == BlockType.DateRange)
                            {
                                rangeBegin = reader.GetDateTime(2).Ticks; //DateTime.Parse(reader["FromDate"].ToString()).Ticks;
                                rangeEnd   = reader.GetDateTime(3).Ticks; //DateTime.Parse(reader["ToDate"].ToString()).Ticks;
                            }
                            else
                            {
                                rangeBegin = long.Parse(reader["FromNumber"].ToString());
                                rangeEnd   = long.Parse(reader["ToNumber"].ToString());
                            }

                            return(new RangeBlock(rangeBlockId, 0, rangeBegin, rangeEnd, lastRangeBlockRequest.BlockType));
                        }
                    }
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }

            return(null);
        }
Example #7
0
        public async Task <LeaseResponse> TryAcquireLeaseAsync(AcquireLeaseRequest acquireLeaseRequest)
        {
            using (SqlConnection conn = await ConnectionHelper.GetOpenConnectionAsync(connectionString))
            {
                SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.Serializable);
                SqlCommand     command     = conn.CreateCommand();
                command.Transaction = transaction;

                try
                {
                    // obtain lock on the record blocking other nodes until the transaction is committed
                    command.CommandText =
                        "UPDATE [RBR].[ResourceGroups] SET LockedByClient = @ClientId WHERE ResourceGroup = @ResourceGroup";
                    command.Parameters.AddWithValue("@ClientId", acquireLeaseRequest.ClientId);
                    command.Parameters.Add("@ResourceGroup", SqlDbType.VarChar, 100).Value =
                        acquireLeaseRequest.ResourceGroup;
                    await command.ExecuteNonQueryAsync();

                    // get the resource group (TODO, use OUTPUT on UPDATE query instead of another query)
                    command.Parameters.Clear();
                    command.CommandText = @"SELECT [ResourceGroup]
      ,[CoordinatorId]
      ,[LastCoordinatorRenewal]
      ,[CoordinatorServer]
      ,[LockedByClient]
      ,[FencingToken]
      ,[LeaseExpirySeconds]
      ,[HeartbeatSeconds]
	  ,GETUTCDATE() AS [TimeNow]
FROM [RBR].[ResourceGroups]
WHERE ResourceGroup = @ResourceGroup";
                    command.Parameters.Add("@ResourceGroup", SqlDbType.VarChar, 100).Value =
                        acquireLeaseRequest.ResourceGroup;

                    ResourceGroup rg = null;
                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (await reader.ReadAsync())
                        {
                            rg = new ResourceGroup
                            {
                                Name                   = acquireLeaseRequest.ResourceGroup,
                                CoordinatorId          = GetGuidFromNullableGuid(reader, "CoordinatorId"),
                                CoordinatorServer      = GetStringFromNullableGuid(reader, "CoordinatorServer"),
                                LastCoordinatorRenewal = GetDateTimeFromNullable(reader, "LastCoordinatorRenewal"),
                                TimeNow                = (DateTime)reader["TimeNow"],
                                LockedByClientId       = GetGuidFromNullableGuid(reader, "LockedByClient"),
                                FencingToken           = (int)reader["FencingToken"],
                                LeaseExpirySeconds     = (int)reader["LeaseExpirySeconds"],
                                HeartbeatSeconds       = (int)reader["HeartbeatSeconds"]
                            };
                        }
                    }

                    if (rg == null)
                    {
                        return(new LeaseResponse
                        {
                            Result = LeaseResult.NoLease,
                            Lease = new Lease
                            {
                                ExpiryPeriod = TimeSpan.FromMinutes(1),
                                HeartbeatPeriod = TimeSpan.FromSeconds(25)
                            }
                        });
                    }

                    // determine the response, if the CoordinatorId is empty or expired then grant, else deny
                    LeaseResponse response = new() { Lease = new Lease() };
                    if (rg.CoordinatorId == Guid.Empty ||
                        (rg.TimeNow - rg.LastCoordinatorRenewal).TotalSeconds > rg.LeaseExpirySeconds)
                    {
                        response.Lease.ResourceGroup   = acquireLeaseRequest.ResourceGroup;
                        response.Lease.ClientId        = acquireLeaseRequest.ClientId;
                        response.Lease.ExpiryPeriod    = TimeSpan.FromSeconds(rg.LeaseExpirySeconds);
                        response.Lease.HeartbeatPeriod = TimeSpan.FromSeconds(rg.HeartbeatSeconds);
                        response.Lease.FencingToken    = ++rg.FencingToken;
                        response.Result = LeaseResult.Granted;

                        command.Parameters.Clear();
                        command.CommandText = @"UPDATE [RBR].[ResourceGroups]
   SET [CoordinatorId] = @ClientId
      ,[LastCoordinatorRenewal] = GETUTCDATE()
      ,[CoordinatorServer] = @Server
      ,[FencingToken] = @FencingToken
 WHERE ResourceGroup = @ResourceGroup";
                        command.Parameters.AddWithValue("@ClientId", acquireLeaseRequest.ClientId);
                        command.Parameters.AddWithValue("@FencingToken", response.Lease.FencingToken);
                        command.Parameters.Add("@Server", SqlDbType.NVarChar, 500).Value       = Environment.MachineName;
                        command.Parameters.Add("@ResourceGroup", SqlDbType.VarChar, 100).Value =
                            acquireLeaseRequest.ResourceGroup;
                        await command.ExecuteNonQueryAsync();
                    }
                    else
                    {
                        response.Lease.ExpiryPeriod    = TimeSpan.FromSeconds(rg.LeaseExpirySeconds);
                        response.Lease.HeartbeatPeriod = TimeSpan.FromSeconds(rg.HeartbeatSeconds);
                        response.Result = LeaseResult.Denied;
                    }

                    transaction.Commit();

                    return(response);
                }
                catch (Exception ex)
                {
                    try
                    {
                        logger.Error("Rolling back lease acquisition: ", ex);
                        transaction.Rollback();
                    }
                    catch (Exception rex)
                    {
                        logger.Error("Rollback of lease acquisition failed: ", rex);
                    }

                    return(new LeaseResponse
                    {
                        Result =
                            TransientErrorDetector.IsTransient(ex) ? LeaseResult.TransientError : LeaseResult.Error,
                        Message = "Lease acquisition failure",
                        Exception = ex
                    });
                }
            }
        }
Example #8
0
        public async Task <IList <ProtoListBlockItem> > GetListBlockItemsAsync(TaskId taskId, string listBlockId)
        {
            var results = new List <ProtoListBlockItem>();

            try
            {
                using (var connection = await CreateNewConnectionAsync(taskId).ConfigureAwait(false))
                {
                    var command = connection.CreateCommand();
                    command.CommandText    = ListBlockQueryBuilder.GetListBlockItems;
                    command.CommandTimeout = ConnectionStore.Instance.GetConnection(taskId).QueryTimeoutSeconds;
                    command.Parameters.Add("@BlockId", SqlDbType.BigInt).Value = long.Parse(listBlockId);

                    using (var reader = await command.ExecuteReaderAsync().ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync().ConfigureAwait(false))
                        {
                            var listBlock = new ProtoListBlockItem();
                            listBlock.ListBlockItemId = reader["ListBlockItemId"].ToString();
                            listBlock.Value           = SerializedValueReader.ReadValueAsString(reader, "Value", "CompressedValue");
                            listBlock.Status          = (ItemStatus)int.Parse(reader["Status"].ToString());

                            if (reader["LastUpdated"] == DBNull.Value)
                            {
                                listBlock.LastUpdated = DateTime.MinValue;
                            }
                            else
                            {
                                listBlock.LastUpdated = reader.GetDateTime(5);
                            }

                            if (reader["StatusReason"] == DBNull.Value)
                            {
                                listBlock.StatusReason = null;
                            }
                            else
                            {
                                listBlock.StatusReason = reader.GetString(6);
                            }

                            if (reader["Step"] == DBNull.Value)
                            {
                                listBlock.Step = null;
                            }
                            else
                            {
                                listBlock.Step = reader.GetByte(7);
                            }

                            results.Add(listBlock);
                        }
                    }
                }
            }
            catch (SqlException sqlEx)
            {
                if (TransientErrorDetector.IsTransient(sqlEx))
                {
                    throw new TransientException("A transient exception has occurred", sqlEx);
                }

                throw;
            }

            return(results);
        }