Fix panic when merging a stalled stream log to an empty LogBuffer (#3744)

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here -->
this fixes an issue submitted by an internal user.

## Description
<!--- Describe your changes in detail -->
If the first event pushed into the log underlying stalled stream
protection, then the log manager would panic. This is because it was
expecting to merge the new event in but there was nothing to merge it
with.

To fix this, I updated the code to `push` the event when the log manager
is empty, instead of merging it.

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
ran existing tests and wrote a new test exercising the
previous-panicking code.

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
This commit is contained in:
Zelda Hessler 2024-07-08 16:20:58 -05:00 committed by GitHub
parent 2295d5b6a8
commit 0c7271664b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 43 additions and 12 deletions

View File

@ -14,5 +14,17 @@
[[smithy-rs]]
message = "Support `stringArray` type in endpoints params"
references = ["smithy-rs#3742"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client"}
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
author = "landonxjames"
[[aws-sdk-rust]]
message = "Fix bug where stalled stream protection would panic with an underflow if the first event was logged too soon."
references = ["smithy-rs#3744"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "Velfi"
[[smithy-rs]]
message = "Fix bug where stalled stream protection would panic with an underflow if the first event was logged too soon."
references = ["smithy-rs#3744"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" }
author = "Velfi"

View File

@ -465,7 +465,7 @@ version = "0.60.3"
[[package]]
name = "aws-smithy-http-server"
version = "0.62.1"
version = "0.63.0"
dependencies = [
"aws-smithy-http 0.60.9",
"aws-smithy-json 0.60.7",
@ -567,9 +567,11 @@ dependencies = [
[[package]]
name = "aws-smithy-protocol-test"
version = "0.60.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31e8279cb24640c7349f2bda6ca818d5fcc85129386bd73c1d0999430d6ddf2"
dependencies = [
"assert-json-diff",
"aws-smithy-runtime-api 1.7.1",
"aws-smithy-runtime-api 1.7.0",
"http 0.2.12",
"pretty_assertions",
"regex-lite",
@ -580,12 +582,10 @@ dependencies = [
[[package]]
name = "aws-smithy-protocol-test"
version = "0.60.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31e8279cb24640c7349f2bda6ca818d5fcc85129386bd73c1d0999430d6ddf2"
version = "0.60.8"
dependencies = [
"assert-json-diff",
"aws-smithy-runtime-api 1.7.0",
"aws-smithy-runtime-api 1.7.1",
"http 0.2.12",
"pretty_assertions",
"regex-lite",
@ -610,7 +610,7 @@ checksum = "d0d3965f6417a92a6d1009c5958a67042f57e46342afb37ca58f9ad26744ec73"
dependencies = [
"aws-smithy-async 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"aws-smithy-http 0.60.8",
"aws-smithy-protocol-test 0.60.7 (registry+https://github.com/rust-lang/crates.io-index)",
"aws-smithy-protocol-test 0.60.7",
"aws-smithy-runtime-api 1.7.0",
"aws-smithy-types 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes",
@ -640,7 +640,7 @@ dependencies = [
"approx",
"aws-smithy-async 1.2.1",
"aws-smithy-http 0.60.9",
"aws-smithy-protocol-test 0.60.7",
"aws-smithy-protocol-test 0.60.8",
"aws-smithy-runtime-api 1.7.1",
"aws-smithy-types 1.2.0",
"bytes",
@ -789,7 +789,7 @@ dependencies = [
name = "aws-smithy-xml"
version = "0.60.8"
dependencies = [
"aws-smithy-protocol-test 0.60.7",
"aws-smithy-protocol-test 0.60.8",
"base64 0.13.1",
"proptest",
"xmlparser",

View File

@ -1,6 +1,6 @@
[package]
name = "aws-smithy-runtime"
version = "1.6.1"
version = "1.6.2"
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "Zelda Hessler <zhessler@amazon.com>"]
description = "The new smithy runtime crate"
edition = "2021"

View File

@ -181,6 +181,7 @@ struct LogBuffer<const N: usize> {
// polling gap. Once the length reaches N, it will never change again.
length: usize,
}
impl<const N: usize> LogBuffer<N> {
fn new() -> Self {
Self {
@ -247,6 +248,11 @@ impl<const N: usize> LogBuffer<N> {
}
counts
}
/// If this LogBuffer is empty, returns `true`. Else, returns `false`.
fn is_empty(&self) -> bool {
self.length == 0
}
}
/// Report/summary of all the events in a time window.
@ -334,7 +340,11 @@ impl ThroughputLogs {
fn push(&mut self, now: SystemTime, value: Bin) {
self.catch_up(now);
self.buffer.tail_mut().merge(value);
if self.buffer.is_empty() {
self.buffer.push(value)
} else {
self.buffer.tail_mut().merge(value);
}
self.buffer.fill_gaps();
}
@ -552,4 +562,13 @@ mod test {
let report = logs.report(start + Duration::from_millis(999));
assert_eq!(ThroughputReport::Pending, report);
}
#[test]
fn test_first_push_succeeds_although_time_window_has_not_elapsed() {
let t0 = SystemTime::UNIX_EPOCH;
let t1 = t0 + Duration::from_secs(1);
let mut tl = ThroughputLogs::new(Duration::from_secs(1), t1);
tl.push_pending(t0);
}
}