Пример #1
0
        /// <summary>
        /// <inheritdoc />
        /// </summary>
        public async Task <TransportMessage[]> Retrieve(CancellationToken cancellationToken, int topMessages)
        {
            var messages = new List <TransportMessage>();

            using (var connection = await _connectionFactory().ConfigureAwait(false))
            {
                if (connection.State != ConnectionState.Open)
                {
                    await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
                }
                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        $@"
DELETE TOP({topMessages}) 
FROM {_tableName} WITH (READPAST, ROWLOCK, READCOMMITTEDLOCK)
OUTPUT deleted.headers, deleted.body
";

                    using (var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
                        {
                            var headers = _headerSerializer.DeserializeFromString((string)reader["headers"]);
                            var body    = (byte[])reader["body"];

                            messages.Add(new TransportMessage(headers, body));
                        }
                    }
                }
            }

            return(messages.ToArray());
        }
        /// <summary>
        /// Gets messages due for delivery at the current time
        /// </summary>
        public async Task <DueMessagesResult> GetDueMessages()
        {
            var connection = await _connectionProvider.GetConnection();

            try
            {
                var dueMessages = new List <DueMessage>();

                const int maxDueTimeouts = 1000;

                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        $@"
SELECT 
    [id],
    [headers],
    [body]
FROM {_tableName.QualifiedName} WITH (UPDLOCK, READPAST, ROWLOCK)
WHERE [due_time] <= @current_time 
ORDER BY [due_time] ASC
";

                    command.Parameters.Add("current_time", SqlDbType.DateTime2).Value = RebusTime.Now.UtcDateTime;

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var id            = (int)reader["id"];
                            var headersString = (string)reader["headers"];
                            var headers       = HeaderSerializer.DeserializeFromString(headersString);
                            var body          = (byte[])reader["body"];

                            var sqlTimeout = new DueMessage(headers, body, async() =>
                            {
                                using (var deleteCommand = connection.CreateCommand())
                                {
                                    deleteCommand.CommandText = $"DELETE FROM {_tableName.QualifiedName} WHERE [id] = @id";
                                    deleteCommand.Parameters.Add("id", SqlDbType.Int).Value = id;
                                    await deleteCommand.ExecuteNonQueryAsync();
                                }
                            });

                            dueMessages.Add(sqlTimeout);

                            if (dueMessages.Count >= maxDueTimeouts)
                            {
                                break;
                            }
                        }
                    }

                    return(new DueMessagesResult(dueMessages, async() =>
                    {
                        using (connection)
                        {
                            await connection.Complete();
                        }
                    }));
                }
            }
            catch (Exception)
            {
                connection.Dispose();
                throw;
            }
        }
Пример #3
0
        /// <summary>
        /// Gets messages due for delivery at the current time
        /// </summary>
        public async Task <DueMessagesResult> GetDueMessages()
        {
            var connection = await _connectionProvider.GetConnectionAsync().ConfigureAwait(false);

            try
            {
                var dueMessages = new List <DueMessage>();

                const int maxDueTimeouts = 1000;

                using (var command = connection.CreateCommand())
                {
                    var tableName = _tableName.QualifiedName;
                    command.CommandText = $@"
                        SELECT id,
                               headers,
                               body
                        FROM {tableName}
                        WHERE due_time <= @current_time 
                        ORDER BY due_time ASC
                        FOR UPDATE";
                    command.Parameters.Add("current_time", MySqlDbType.DateTime).Value = _rebusTime.Now.UtcDateTime;

                    using (var reader = await command.ExecuteReaderAsync().ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync().ConfigureAwait(false))
                        {
                            var id            = (long)reader["id"];
                            var headersString = (string)reader["headers"];
                            var headers       = HeaderSerializer.DeserializeFromString(headersString);
                            var body          = (byte[])reader["body"];

                            var sqlTimeout = new DueMessage(headers, body, async() =>
                            {
                                using (var deleteCommand = connection.CreateCommand())
                                {
                                    deleteCommand.CommandText = $"DELETE FROM {tableName} WHERE id = {id}";
                                    await deleteCommand.ExecuteNonQueryAsync().ConfigureAwait(false);
                                }
                            });

                            dueMessages.Add(sqlTimeout);

                            if (dueMessages.Count >= maxDueTimeouts)
                            {
                                break;
                            }
                        }
                    }

                    return(new DueMessagesResult(dueMessages, async() =>
                    {
                        using (connection)
                        {
                            await connection.CompleteAsync().ConfigureAwait(false);
                        }
                    }));
                }
            }
            catch (Exception)
            {
                connection.Dispose();
                throw;
            }
        }