如何检查存储队列是否包含特定消息
How to check if a storage queue contains a specific message
我正在为存储队列触发的 azure 函数编写集成测试,我希望能够检查该函数是否已成功处理消息或将消息移至毒物队列。
有什么方法可以在队列中搜索特定消息而不使消息出列吗?
我的做法是获取发送消息的messageId和popReceipt,然后尝试更新消息,找不到则抛出异常。
public async Task<bool> IsMessageInQueue(string messageId, string popReceipt, string queueName)
{
try
{
var client = new QueueClient(_storageConnectionString, queueName);
_ = client.UpdateMessageAsync(messageId, popReceipt);
return true; //exists in queue
}
catch (Exception)
{
return false; //doesn't exist in queue
}
}
然后
var sendMessageResponse = await client.SendMessageAsync(queueMessage);
var messageId = sendMessageResponse.Value.MessageId;
var popReceipt = sendMessageResponse.Value.PopReceipt;
var isProcessing = IsMessageInQueue(messageId, popReceipt, "processing");
var isPoisoned = IsMessageInQueue(messageId, popReceipt, "processing-poison");
isProcessing
如果消息尚未被函数接收并且仍在“处理中”,则 return 为真,但问题是当消息被接收时 messageId 会发生变化移动到有毒队列,所以 isPoisoned
将始终 return false
更新:
感谢 @gaurav-mantri 的建议,我更新了使用 PeekMessagesAsync 的方法并在下面添加了我的答案:
Is there any way to search a queue for a specific message, without
dequeuing the message?
只有当队列中的消息数少于 32 时才有可能。32 是您一次可以查看(或出队)的最大消息数。
如果消息数少于32条,您可以使用QueueClient.PeekMessagesAsync
并将您的消息的消息id与返回的消息进行比较。如果找到匹配的消息 ID,则表示消息存在于队列中。
感谢@gaurav-mantri 的建议,我更新了使用 PeekMessagesAsync 的方法
public async Task<bool> IsMessageInQueue(BinaryData body, string queueName)
{
var client = new QueueClient(_storageConnectionString, queueName);
var messages = await client.PeekMessagesAsync();
return messages.Value.Any(x => x.Body.ToString().Equals(body.ToString()));
}
这是用法...
var queueMessage = JsonConvert.SerializeObject("hi");
var sendMessageResponse = await client.SendMessageAsync(queueMessage);
var isProcessing = IsMessageInQueue(new BinaryData(queueMessage), "processing");
var isPoisoned = IsMessageInQueue(new BinaryData(queueMessage), "processing-poison");
我正在为存储队列触发的 azure 函数编写集成测试,我希望能够检查该函数是否已成功处理消息或将消息移至毒物队列。
有什么方法可以在队列中搜索特定消息而不使消息出列吗?
我的做法是获取发送消息的messageId和popReceipt,然后尝试更新消息,找不到则抛出异常。
public async Task<bool> IsMessageInQueue(string messageId, string popReceipt, string queueName)
{
try
{
var client = new QueueClient(_storageConnectionString, queueName);
_ = client.UpdateMessageAsync(messageId, popReceipt);
return true; //exists in queue
}
catch (Exception)
{
return false; //doesn't exist in queue
}
}
然后
var sendMessageResponse = await client.SendMessageAsync(queueMessage);
var messageId = sendMessageResponse.Value.MessageId;
var popReceipt = sendMessageResponse.Value.PopReceipt;
var isProcessing = IsMessageInQueue(messageId, popReceipt, "processing");
var isPoisoned = IsMessageInQueue(messageId, popReceipt, "processing-poison");
isProcessing
如果消息尚未被函数接收并且仍在“处理中”,则 return 为真,但问题是当消息被接收时 messageId 会发生变化移动到有毒队列,所以 isPoisoned
将始终 return false
更新:
感谢 @gaurav-mantri 的建议,我更新了使用 PeekMessagesAsync 的方法并在下面添加了我的答案:
Is there any way to search a queue for a specific message, without dequeuing the message?
只有当队列中的消息数少于 32 时才有可能。32 是您一次可以查看(或出队)的最大消息数。
如果消息数少于32条,您可以使用QueueClient.PeekMessagesAsync
并将您的消息的消息id与返回的消息进行比较。如果找到匹配的消息 ID,则表示消息存在于队列中。
感谢@gaurav-mantri 的建议,我更新了使用 PeekMessagesAsync 的方法
public async Task<bool> IsMessageInQueue(BinaryData body, string queueName)
{
var client = new QueueClient(_storageConnectionString, queueName);
var messages = await client.PeekMessagesAsync();
return messages.Value.Any(x => x.Body.ToString().Equals(body.ToString()));
}
这是用法...
var queueMessage = JsonConvert.SerializeObject("hi");
var sendMessageResponse = await client.SendMessageAsync(queueMessage);
var isProcessing = IsMessageInQueue(new BinaryData(queueMessage), "processing");
var isPoisoned = IsMessageInQueue(new BinaryData(queueMessage), "processing-poison");