-
Notifications
You must be signed in to change notification settings - Fork 615
Closed
Description
Hi,
It looks I've accidentally found an amusing bug. Let me start from this example(by the way, I'm using v6.2.1):
using System;
using System.Collections.Generic;
using System.Threading;
using RabbitMQ.Client;
namespace DotNetExperiments
{
public static class Program
{
private static readonly ReadOnlyMemory<byte> SentBody = new byte[] {42, 42, 42, 42, 42};
public static void Main()
{
// Boostrap stuff
var connectionFactory = new ConnectionFactory
{
Uri = new Uri("amqps://apwlvbny:ZPrB0qqbBkBE0jOwUAHERRXL39fog2jc@rattlesnake.rmq.cloudamqp.com/apwlvbny")
};
var connection = connectionFactory.CreateConnection();
var model = connection.CreateModel();
var queue = Guid.NewGuid().ToString("N");
model.QueueDeclare(queue, false, false);
// Let's store all received bodies
var receivedBodies = new List<ReadOnlyMemory<byte>>();
while (true)
{
Thread.Sleep(100);
// Then every iteration we recheck all received bodies: they should match with sentBody
foreach (var receivedBody in receivedBodies) CheckReceivedBody(receivedBody);
model.BasicPublish("", queue, true, null, SentBody);
var getResult = model.BasicGet(queue, true);
if (getResult == null)
continue;
// Store received body
receivedBodies.Add(getResult.Body);
}
}
private static void CheckReceivedBody(ReadOnlyMemory<byte> receivedBody)
{
if (receivedBody.Span.SequenceEqual(SentBody.Span))
return;
Console.WriteLine($"Mismatch: {string.Join(",", receivedBody.Span.ToArray())} != {string.Join(",", SentBody.Span.ToArray())}");
}
}
}
After a couple of seconds mismatches have been found:
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
Mismatch: 8,0,0,0,0 != 42,42,42,42,42
An array under BasicGetResult.Body was reused.
The reason of it might be the following: after a completion of BasicGet RPC continuation, a command is disposed and an array under BasicGetResult.Body is returned to ArrayPool. This makes usage of BasicGetResult.Body unpredictable at least(EasyNetQ/EasyNetQ#1153) because it is unsafe to use BasicGetResult.Body right after model.BasicGet returns it.
It looks like the only fix is to copy a body a bit before a completion of a continuation.
Could you please confirm the issue?
Metadata
Metadata
Assignees
Labels
No labels