/// <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; } }
/// <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; } }