softwaremill / elasticmq

In-memory message queue with an Amazon SQS-compatible interface. Runs stand-alone or embedded.
https://softwaremill.com/open-source/
Apache License 2.0
2.53k stars 193 forks source link

Feature Request: ReceiptHandles #2

Closed ttonelli closed 11 years ago

ttonelli commented 11 years ago

I am using ElasticMQ to test code that will be used with SQS. Thus, it is important for me that ElasticMQ conforms with the behavior of SQS, even if that's a bit weird.

One of the features of SQS is that it returns a ReceiptHandle on receive calls. This handle is then used in "delete" and "set visibility" messages to determine the message to delete and to change the visibility.

In SQS, the idea is that the handle must be different than the message id because only the last consumer to get the message has the right to delete it. That is, if consumer A gets message M, then the message timeout expires, then consumer B gets message M, only consumer B is allowed to delete it. A delete request from A should not throw an error, but the message should not be deleted.

However, ElasticMQ does not implement this behavior. The returned receipt handle is always the same as the message id, and on "delete", the receipt handle is treated as a message id.

So, do you think it's possible to bring ElasticMQ's behavior closer to SQS? All what's needed is to generate a receipt handle at "receive" (using UUID's random, for example), and then keep a map in the server from message id to last receipt handle to ensure that the client requesting a delete or set visibility is allowed to do that. That would be trivial for InMemoryStorage, but I imagine there would be other implications for distributed environments.

adamw commented 11 years ago

Could you try 0.6.2-SNAPSHOT?

ttonelli commented 11 years ago

Hi,

sorry for taking so long, I didn't receive any message about your comments here.

So, I tried to test with 0.6.2-SNAPSHOT, but I couldn't. I noticed that the messages now have receipts that have some #nr appended to the id, and I confirm that I can delete them using the receipt.

The problem is that to test whether only the last client can delete, I need to be able to change the visibility of the message in the queue, so that another client can get it. But it seems that ChangeMessageVisibilityRequest is failing.

I simply get a message from the queue and then send a message more or less like this:

ChangeMessageVisibilityRequest request = new ChangeMessageVisibilityRequest( getQueueUrl(), msg.getReceipt(), 0);

// where _sqs is amazon's client pointing to the queue _sqs.changeMessageVisibility(request);

And this returns an exception:

Status Code: 400, AWS Service: AmazonSQS, AWS Request ID: 00000000-0000-0000-0000-000000000000, AWS Error Code: InvalidParameterValue, AWS Error Message: See the SQS docs.

Can you reproduce this error too?

adamw commented 11 years ago

Ah, I wasn't using the receipt handle when changing the message visibility. New snapshot (fixed) uploaded.

ttonelli commented 11 years ago

Hi,

yes, I can confirm that visibility works and that the receipts are working like SQS too (at least for in memory storage, which is what I am using).

Thanks!

adamw commented 11 years ago

Great! I'll do a release soon then.