Peeking on an empty Queue. Is it possible to return early
AhyaanTech opened this issue · 6 comments
When peeking on an empty queues it awaits for some time and gives the following error
warning: `rust_lib_azure` (lib test) generated 2 warnings (run `cargo fix --lib -p rust_lib_azure_bus --tests` to apply 2 suggestions)
Finished `test` profile [unoptimized + debuginfo] target(s) in 2.44s
Running unittests src\lib.rs (target\debug\deps\rust_lib_azure_bus-b9a918f953b77c77.exe)
running 1 test
test api::reciever::test::test_peek_messages ... ok
successes:
---- api::reciever::test::test_peek_messages stdout ----
Err(Error decoding from message
Caused by:
Error decoding from message)
successes:
api::reciever::test::test_peek_messages
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 12.79s
as you can see 12.79s is quite long. is it possible to return early before it tries to decode the message?
#[tokio::main]
pub async fn peek_messages(
connection_string: String,
queue_name: String,
message_count: u32,
) -> anyhow::Result<Vec<AzureQueueMessage>> {
let mut client = ServiceBusClient::new_from_connection_string(
connection_string,
ServiceBusClientOptions::default(),
)
.await?;
let mut receiver = client
.create_receiver_for_queue(queue_name, Default::default())
.await?;
let messages = receiver.peek_messages(message_count, None).await;
match messages {
Ok(messages) => {
let azure_messages: Vec<AzureQueueMessage> = messages
.iter()
.map(|message| {
let message_id = message.message_id().map(|id| id.into_owned());
AzureQueueMessage {
system_properties: MessageSystemProperties {
message_id,
..Default::default()
},
..Default::default()
}
})
.collect();
Result::Ok(azure_messages)
}
Err(error) => anyhow::bail!(error),
}
}
As suggested here (https://learn.microsoft.com/en-us/answers/questions/222488/peeklock-empty-topic-queue-takes-longer-than-expec), the duration that the server waits before returning an empty response is determined by the timeout parameter in the request message, and this currently matches to the try_timeout
parameter in ServiceBusClientOptions
.
This, however, indeed shows two problems with the current implementation
- An empty peek message response is not interpreted properly
- The user should be able to set this timeout parameter
This is confirmed a bug after some investigation.
The SB server doesn't wait seem to wait for the whole duration of try_timeout
before returning a response of NO_CONTENT
, and other than the server response time, the long duration is also caused by:
- the
NO_CONTENT
response is not interpreted properly - failing to decode the response causes the retry policy to retry the operation for 3 times (the default number of retries), and the retry policy waits for a short period of time before attempting the next retry
Fixing this does not require a breaking change.
@AhyaanTech This should be fixed in 0.20.1.
Please note that the expected behaviour is to get an empty vector if the queue is empty
Fixed!
running 1 test
test api::reciever::test::test_peek_messages ... ok
successes:
---- api::reciever::test::test_peek_messages stdout ----
Ok(
[],
)
successes:
api::reciever::test::test_peek_messages
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.28s