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