Пример #1
0
        /// <inheritdoc />
        public IReceivedMessageInternal GetNextMessage(List <string> routes)
        {
            if (routes != null && routes.Count > 0)
            {
                throw new NotSupportedException("The in-memory transport does not support routes");
            }

            if (!Queues[_connectionInformation].TryDequeue(out var id))
            {
                return(null);
            }
            if (!QueueData[_connectionInformation].TryRemove(id, out var item))
            {
                return(null);
            }

            var hasError = false;

            try
            {
                var newMessage = _messageFactory.Create(item.Body, item.Headers);

                if (!string.IsNullOrEmpty(item.JobName))
                {
                    var key = GenerateKey(item.JobName);

                    //add it to the cache
                    JobLastEventCache.Execute(context => item.JobEventTime, new Context(key));
                }

                Interlocked.Increment(ref DequeueCounts[_connectionInformation].ProcessedCount);

                return(_receivedMessageFactory.Create(newMessage,
                                                      new MessageQueueId(id),
                                                      new MessageCorrelationId(item.CorrelationId)));
            }
            catch (Exception error)
            {
                hasError = true;
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message", error,
                          new MessageQueueId(id), null, null, null);
            }
            finally
            {
                if (!hasError)
                {
                    QueueWorking[_connectionInformation].TryAdd(item.Id, item);
                }
            }
        }
Пример #2
0
        internal IReceivedMessageInternal HandleMessage(Schema.QueueTable queueRecord, int queueId, Guid correlationId)
        {
            if (queueRecord == null)
            {
                return(null);
            }

            //load up the message from the DB
            int id = queueId;

            byte[] headerPayload  = null;
            byte[] messagePayload = null;
            try
            {
                headerPayload  = queueRecord.Headers;
                messagePayload = queueRecord.Body;

                var headers =
                    _serialization.InternalSerializer
                    .ConvertBytesTo <IDictionary <string, object> >(
                        headerPayload);

                var messageGraph =
                    (MessageInterceptorsGraph)
                    headers[_headers.StandardHeaders.MessageInterceptorGraph.Name];

                var message =
                    _serialization.Serializer.BytesToMessage <MessageBody>(
                        messagePayload,
                        messageGraph, headers).Body;
                var newMessage = _messageFactory.Create(message, headers);

                return(_receivedMessageFactory.Create(newMessage,
                                                      new MessageQueueId <int>(id),
                                                      new MessageCorrelationId <Guid>(correlationId)));
            }
            catch (Exception err)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a de-queued message",
                          err, new MessageQueueId <int>(id),
                          new MessageCorrelationId <Guid>(correlationId),
                          messagePayload,
                          headerPayload);
            }
        }
Пример #3
0
        public IReceivedMessageInternal Read(SqlDataReader reader)
        {
            if (!reader.Read())
            {
                return(null);
            }

            //load up the message from the DB
            long id            = 0;
            var  correlationId = Guid.Empty;

            byte[] headerPayload  = null;
            byte[] messagePayload = null;
            try
            {
                id             = (long)reader["queueid"];
                correlationId  = (Guid)reader["CorrelationID"];
                headerPayload  = (byte[])reader["Headers"];
                messagePayload = (byte[])reader["body"];

                var headers      = _serialization.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(headerPayload);
                var messageGraph = (MessageInterceptorsGraph)headers[_headers.StandardHeaders.MessageInterceptorGraph.Name];
                var message      = _serialization.Serializer.BytesToMessage <MessageBody>(messagePayload, messageGraph).Body;
                var newMessage   = _messageFactory.Create(message, headers);

                return(_receivedMessageFactory.Create(newMessage,
                                                      new MessageQueueId(id),
                                                      new MessageCorrelationId(correlationId)));
            }
            catch (Exception error)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from the SQL server", error, new MessageQueueId(id), new MessageCorrelationId(correlationId), messagePayload, headerPayload);
            }
        }
        /// <inheritdoc />
        public RedisMessage Handle(ReceiveMessageQuery query)
        {
            byte[] message = null;
            byte[] headers = null;
            string messageId;
            var    poisonMessage = false;
            RedisQueueCorrelationIdSerialized correlationId = null;

            try
            {
                var          unixTimestamp = _unixTimeFactory.Create().GetCurrentUnixTimestampMilliseconds();
                RedisValue[] result;
                if (query.MessageId != null && query.MessageId.HasValue)
                {
                    result = _dequeueRpcLua.Execute(query.MessageId.Id.Value.ToString(), unixTimestamp);
                }
                else
                {
                    result = _dequeueLua.Execute(unixTimestamp);
                }

                if (result == null || result.Length == 1 && !result[0].HasValue || !result[0].HasValue)
                {
                    return(null);
                }

                if (!result[1].HasValue)
                {
                    //at this point, the record has been de-queued, but it can't be processed.
                    poisonMessage = true;
                }

                messageId = result[0];
                var id = new RedisQueueId(messageId);
                query.MessageContext.MessageId = id;
                if (!poisonMessage)
                {
                    message = result[1];
                    headers = result[2];
                    if (result[3].HasValue)
                    {
                        if (result[3].TryParse(out long messageExpiration))
                        {
                            if (messageExpiration - unixTimestamp < 0)
                            {
                                //message has expired
                                _deleteMessage.Handle(new DeleteMessageCommand(new RedisQueueId(messageId)));
                                return(new RedisMessage(messageId, null, true));
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                throw new ReceiveMessageException("Failed to dequeue a message", error);
            }

            if (poisonMessage)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from Redis; a messageId was returned, but the LUA script returned a null message. The message payload has most likely been lost.", null,
                          new RedisQueueId(messageId), new RedisQueueCorrelationId(Guid.Empty),
                          null, null);
            }

            try
            {
                var allHeaders = _serializer.InternalSerializer.ConvertBytesTo <IDictionary <string, object> > (headers);
                correlationId = (RedisQueueCorrelationIdSerialized)allHeaders[_redisHeaders.CorrelationId.Name];
                var messageGraph = (MessageInterceptorsGraph)allHeaders[_redisHeaders.Headers.StandardHeaders.MessageInterceptorGraph.Name];
                var messageData  = _serializer.Serializer.BytesToMessage <MessageBody>(message, messageGraph);

                var newMessage = _messageFactory.Create(messageData.Body, allHeaders);

                return(new RedisMessage(
                           messageId,
                           _receivedMessageFactory.Create(
                               newMessage,
                               new RedisQueueId(messageId),
                               new RedisQueueCorrelationId(correlationId.Id)), false));
            }
            catch (Exception error)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from redis", error,
                          new RedisQueueId(messageId), new RedisQueueCorrelationId(correlationId),
                          message, headers);
            }
        }
Пример #5
0
        internal IReceivedMessageInternal HandleMessage(IDbConnection connection, IDbTransaction transaction, IDataReader reader, CommandString commandString)
        {
            if (!reader.Read())
            {
                return(null);
            }

            //load up the message from the DB
            long id            = 0;
            var  correlationId = Guid.Empty;

            byte[] headerPayload  = null;
            byte[] messagePayload = null;
            try
            {
                id = (long)reader["QueueID"];
                var cId = (string)reader["CorrelationID"];
                headerPayload  = (byte[])reader["Headers"];
                messagePayload = (byte[])reader["Body"];

                //before we continue, run the commands and commit the transaction
                //otherwise, poison messages will conflict
                foreach (var additionalCommand in commandString.AdditionalCommands)
                {
                    using (var command = connection.CreateCommand())
                    {
                        command.Transaction = transaction;
                        command.CommandText = additionalCommand;
                        command.ExecuteNonQuery();
                    }
                }
                transaction.Commit();

                correlationId = new Guid(cId);
                var headers =
                    _serialization.InternalSerializer
                    .ConvertBytesTo <IDictionary <string, object> >(
                        headerPayload);

                var messageGraph =
                    (MessageInterceptorsGraph)
                    headers[_headers.StandardHeaders.MessageInterceptorGraph.Name];

                var message =
                    _serialization.Serializer.BytesToMessage <MessageBody>(
                        messagePayload,
                        messageGraph, headers).Body;
                var newMessage = _messageFactory.Create(message, headers);

                return(_receivedMessageFactory.Create(newMessage,
                                                      new MessageQueueId <long>(id),
                                                      new MessageCorrelationId <Guid>(correlationId)));
            }
            catch (Exception err)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from SQLite",
                          err, new MessageQueueId <long>(id),
                          new MessageCorrelationId <Guid>(correlationId),
                          messagePayload,
                          headerPayload);
            }
        }
        /// <inheritdoc />
        public IReceivedMessageInternal Handle(ReceiveMessageQuery <NpgsqlConnection, NpgsqlTransaction> query)
        {
            using (var selectCommand = query.Connection.CreateCommand())
            {
                selectCommand.Transaction = query.Transaction;
                selectCommand.CommandText =
                    ReceiveMessage.GetDeQueueCommand(_commandCache, _tableNameHelper, _options.Value,
                                                     query.Routes);

                selectCommand.Parameters.Add("@CurrentDate", NpgsqlDbType.Bigint);
                selectCommand.Parameters["@CurrentDate"].Value = _getTime.GetCurrentUtcDate().Ticks;

                if (_options.Value.EnableRoute && query.Routes != null && query.Routes.Count > 0)
                {
                    var routeCounter = 1;
                    foreach (var route in query.Routes)
                    {
                        selectCommand.Parameters.Add("@Route" + routeCounter, NpgsqlDbType.Varchar);
                        selectCommand.Parameters["@Route" + routeCounter].Value = route;
                        routeCounter++;
                    }
                }

                using (var reader = selectCommand.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        return(null);
                    }

                    //load up the message from the DB
                    long   id             = 0;
                    var    correlationId  = Guid.Empty;
                    byte[] headerPayload  = null;
                    byte[] messagePayload = null;
                    try
                    {
                        id             = (long)reader["queueid"];
                        correlationId  = (Guid)reader["CorrelationID"];
                        headerPayload  = (byte[])reader["Headers"];
                        messagePayload = (byte[])reader["body"];

                        var headers =
                            _serialization.InternalSerializer
                            .ConvertBytesTo <IDictionary <string, object> >(headerPayload);
                        var messageGraph =
                            (MessageInterceptorsGraph)headers[_headers.StandardHeaders.MessageInterceptorGraph.Name];
                        var message = _serialization.Serializer
                                      .BytesToMessage <MessageBody>(messagePayload, messageGraph, headers).Body;
                        var newMessage = _messageFactory.Create(message, headers);

                        return(_receivedMessageFactory.Create(newMessage,
                                                              new MessageQueueId <long>(id),
                                                              new MessageCorrelationId <Guid>(correlationId)));
                    }
                    catch (Exception error)
                    {
                        //at this point, the record has been de-queued, but it can't be processed.
                        throw new PoisonMessageException(
                                  "An error has occurred trying to re-assemble a message de-queued from the server ", error,
                                  new MessageQueueId <long>(id), new MessageCorrelationId <Guid>(correlationId), messagePayload,
                                  headerPayload);
                    }
                }
            }
        }
Пример #7
0
        /// <inheritdoc />
        public IReceivedMessageInternal GetNextMessage(List <string> routes, TimeSpan timeout)
        {
            if (_complete)
            {
                return(null);
            }

            if (routes != null && routes.Count > 0)
            {
                throw new NotSupportedException("The in-memory transport does not support routes");
            }

            using (CancellationTokenSource linkedCts =
                       CancellationTokenSource.CreateLinkedTokenSource(_cancelToken.CancelWorkToken,
                                                                       _cancelToken.StopWorkToken))
            {
                Guid id = Guid.Empty;
                try
                {
                    if (!Queues[_connectionInformation].TryTake(out id, Convert.ToInt32(timeout.TotalMilliseconds), linkedCts.Token))
                    {
                        return(null);
                    }
                }
                catch (OperationCanceledException)
                {
                    return(null);
                }

                if (!QueueData[_connectionInformation].TryRemove(id, out var item))
                {
                    return(null);
                }

                var hasError = false;
                try
                {
                    var newMessage = _messageFactory.Create(item.Body, item.Headers);

                    if (!string.IsNullOrEmpty(item.JobName))
                    {
                        var key = GenerateKey(item.JobName);

                        //add it to the cache
                        JobLastEventCache.Execute(context => item.JobEventTime, new Context(key));
                    }

                    Interlocked.Increment(ref DequeueCounts[_connectionInformation].ProcessedCount);

                    return(_receivedMessageFactory.Create(newMessage,
                                                          new MessageQueueId(id),
                                                          new MessageCorrelationId(item.CorrelationId)));
                }
                catch (Exception error)
                {
                    hasError = true;
                    //at this point, the record has been de-queued, but it can't be processed.
                    throw new PoisonMessageException(
                              "An error has occurred trying to re-assemble a message", error,
                              new MessageQueueId(id), null, null, null);
                }
                finally
                {
                    if (!hasError)
                    {
                        QueueWorking[_connectionInformation].TryAdd(item.Id, item);
                    }
                }
            }
        }