private async Task <int> ProcessMessageCallbacks(NpgsqlConnection connection, PostgreSqlBusMessage message, List <Func <IBusMessage, Task> > callbacks, Guid queueMessageId) { var timer = Stopwatch.StartNew(); for (var i = 0; i < callbacks.Count; i++) { var callback = callbacks[i]; try { await callback(message).ConfigureAwait(false); } catch (Exception e) { await _db.UpdateMessageState(connection, queueMessageId, e.ToString(), MessageState.Failed).ConfigureAwait(false); throw new CallbackExecutionException(i, queueMessageId, e); } } timer.Stop(); await _db.UpdateMessageState(connection, queueMessageId, $"Time spent={timer.Elapsed};", MessageState.Completed).ConfigureAwait(false); return(callbacks.Count); }
private async Task <int> ProcessQueue(List <Func <IBusMessage, Task> > callbacks, string stateProcessor, Queue queue) { var callbackCounter = 0; using (var connection = new NpgsqlConnection(_options.ConnectionString)) { await connection.OpenAsync().ConfigureAwait(false); try { using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) { try { var queueMessageId = await _db.FetchNextQueueMessageId(connection, queue, stateProcessor).ConfigureAwait(false); if (queueMessageId.HasValue) { _logger.LogDebug("Received message id: {ReceivedMessageId}", queueMessageId); var queueMessage = await _db.FetchQueueMessageAsync(connection, queueMessageId.Value).ConfigureAwait(false); if (queueMessage == null) { _logger.LogWarning("Received message not loaded by id: {ReceivedMessageId}", queueMessageId); return(0); } // did we loaded wrong message? if (queueMessage.StateProcessor != stateProcessor) { _logger.LogWarning( "Received message id: '{ReceivedMessageId}' state processor does not match. Expected: {ExpectedStateProcessor}. Received: {ReceivedStateProcessor}.", queueMessageId, stateProcessor, queueMessage.StateProcessor); return(0); } var messageId = queueMessage.QueueMessageId.ToString(); var body = Encoding.UTF8.GetBytes(queueMessage.Body); var properties = _serializer.Deserialize <IDictionary <string, object> >(queueMessage.Properties); var busMessage = new PostgreSqlBusMessage(messageId, body, properties); callbackCounter = await ProcessMessageCallbacks(connection, busMessage, callbacks, queueMessageId.Value).ConfigureAwait(false); } await transaction.CommitAsync().ConfigureAwait(false); } catch (CallbackExecutionException) { // save message state await transaction.CommitAsync().ConfigureAwait(false); throw; } catch { await transaction.RollbackAsync().ConfigureAwait(false); throw; } } } finally { connection.Close(); } } return(callbackCounter); }