I'm busy experimenting with SQS. From my understanding, a visibility timeout makes a message unavailable to other consumers for the length of that visibility timeout. From my experience, though, this appears to not be the case. It appears that a visibility timeout makes all messages in that queue unavailable.
I have code which confirms this:
SendMessageRequest messageRequest = new SendMessageRequest()
.withMessageBody("first one")
.withMessageDeduplicationId(UUID.randomUUID().toString())
.withQueueUrl(queueAddress)
.withMessageGroupId("test1");
sqs.sendMessage(messageRequest);
messageRequest = new SendMessageRequest()
.withMessageBody("second one")
.withMessageDeduplicationId(UUID.randomUUID().toString())
.withQueueUrl(queueAddress)
.withMessageGroupId("test1");
sqs.sendMessage(messageRequest);
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueAddress);
new Thread(() -> {
System.out.println("t1");
List<Message> messages = sqs.receiveMessage(receiveMessageRequest
.withMaxNumberOfMessages(1)
.withMessageAttributeNames("All")
.withVisibilityTimeout(5)
.withWaitTimeSeconds(1)
).getMessages();
System.out.println(messages.get(0).getBody());
}).start();
new Thread(() -> {
System.out.println("t2");
List<Message> messages = sqs.receiveMessage(receiveMessageRequest
.withMaxNumberOfMessages(1)
.withMessageAttributeNames("All")
.withVisibilityTimeout(5)
.withWaitTimeSeconds(1)
).getMessages();
System.out.println(messages.get(0).getBody());
}).start();
What happens is that the second thread throws an IndexOutOfBoundsException. This is because no messages are available to it. This confirms that the visibility timeout affects the entire queue and not just the message.
Unfortunately, this does not seem to be in line withe Amazon's documentation.
If anyone has any insight as to why this is the case, or if I am misusing the SQS SDK, please let me know :)