Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XRay Remote Sampler - Cap quotaBalance to 1x quota #3652

Merged
merged 12 commits into from
May 25, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- AWS SDK rename attributes `aws.operation`, `aws.service` to `rpc.method`,`rpc.service` in `go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws`. (#3582, #3617)
- AWS SDK span name to be of the format `Service.Operation` in `go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws`. (#3582, #3521)
- Prevent sampler configuration reset from erroneously sampling first span in `go.opentelemetry.io/contrib/samplers/jaegerremote`. (#3603, #3604)
- AWS XRay Remote Sampling to cap quotaBalance to 1x quota in `go.opentelemetry.io/contrib/samplers/aws/xray`. (#3651, #3652)

## [1.16.0-rc.1/0.41.0-rc.1/0.10.0-rc.1] - 2023-03-02

Expand Down
8 changes: 4 additions & 4 deletions samplers/aws/xray/internal/reservoir.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ func (r *reservoir) refreshQuotaBalanceLocked(now time.Time, borrowed bool) { //
r.quotaBalance += elapsedTime.Seconds()
}
} else {
totalQuotaBalanceCapacity := elapsedTime.Seconds() * r.capacity
r.quotaBalance += elapsedTime.Seconds() * r.quota
elapsedSeconds := elapsedTime.Seconds()
r.quotaBalance += elapsedSeconds * r.quota

if r.quotaBalance > totalQuotaBalanceCapacity {
r.quotaBalance = totalQuotaBalanceCapacity
if r.quotaBalance > r.quota {
r.quotaBalance = r.quota
}
}
}
25 changes: 13 additions & 12 deletions samplers/aws/xray/internal/reservoir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,15 @@ func TestConsumeFromReservoir(t *testing.T) {
// once assigned quota is consumed reservoir does not allow to consume in that second
assert.False(t, r.take(clock.now(), false, 1.0))

// increase the clock by 5
// increase the clock by 4
clock.nowTime = 1500000005

// elapsedTime is 4 seconds so quota balance should be elapsedTime * quota = 8 and below take would consume 1 so
// ultimately 7
// reservoir updates the quotaBalance with one second worth of quota (even though 4 seconds have passed) and allows to consume
assert.Equal(t, r.quotaBalance, 0.0)
assert.True(t, r.take(clock.now(), false, 1.0))
assert.Equal(t, r.quotaBalance, 7.0)
assert.Equal(t, r.quotaBalance, 1.0)
assert.True(t, r.take(clock.now(), false, 1.0))
assert.Equal(t, r.quotaBalance, 0.0)
}

func TestZeroCapacityFailBorrow(t *testing.T) {
Expand Down Expand Up @@ -213,23 +215,22 @@ func TestResetQuotaUsageRotation(t *testing.T) {
assert.True(t, r.take(clock.now(), false, 1.0))
}

// assert that when quotaBalance exceeds totalQuotaBalanceCapacity then totalQuotaBalanceCapacity
// gets assigned to quotaBalance.
func TestQuotaBalanceNonBorrowExceedsCapacity(t *testing.T) {
// assert that when quotaBalance is assigned the correct value after a portion of a second.
func TestQuotaBalanceAfterPortionOfSecond(t *testing.T) {
clock := &mockClock{
nowTime: 1500000001,
nowTime: 1500000002,
}

r := &reservoir{
quota: 6,
capacity: 5,
lastTick: time.Unix(1500000000, 0),
capacity: 6,
lastTick: time.Unix(1500000001, 500000000),
}

r.refreshQuotaBalanceLocked(clock.now(), false)

// assert that if quotaBalance exceeds capacity then total capacity would be new quotaBalance
assert.Equal(t, r.quotaBalance, r.capacity)
// assert that after half a second, quotaBalance is now quota*0.5 = 3
assert.Equal(t, r.quotaBalance, 3.0)
}

// assert quotaBalance and capacity of borrowing case.
Expand Down