Пример #1
0
        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);
        }
Пример #2
0
        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);
        }