Skip to content

fix(eventhubs): stop authorization refresh on close - #5119

Merged
Johnathan W (j7nw4r) merged 14 commits into
Azure:mainfrom
j7nw4r:fix/eventhubs-producer-memory-leak
Sep 1, 2026
Merged

fix(eventhubs): stop authorization refresh on close#5119
Johnathan W (j7nw4r) merged 14 commits into
Azure:mainfrom
j7nw4r:fix/eventhubs-producer-memory-leak

Conversation

@j7nw4r

@j7nw4r Johnathan W (j7nw4r) commented Aug 24, 2026

Copy link
Copy Markdown
Member

Summary

Event Hubs ProducerClient close cycles retain authorization refresh task references and can cause sustained heap growth.

Motivation

The owned authorization refresh task keeps connection and authorizer references alive during connection teardown. This prevents producer lifecycle memory from being released promptly and matches the reported growth of about 4.8 KB per cycle.

Changes

Stops the owned authorization refresh task before RecoverableConnection teardown. Close aborts the refresh task and awaits its cancellation, so task-held references are released before close returns.

Replaces OnceLock<SpawnedTask> with a mutex-backed state machine. This removes the unsafe Send and Sync implementations.

Adds a deterministic regression test for the owned authorization refresh task and documents the fix in the 0.15.0 changelog.

Test plan

  • cargo fmt -p azure_messaging_eventhubs -- --check passed.
  • cargo clippy -p azure_messaging_eventhubs --all-features --all-targets -- -D warnings passed.
  • cargo test -p azure_messaging_eventhubs --all-features passed. Tests configured for live service access remained skipped.
  • The focused deterministic regression and git diff --check passed.

Closes #4595

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
3 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Stops Event Hubs authorization refresh tasks during connection closure to prevent retained producer lifecycle memory.

Changes:

  • Cancels refresh tasks before connection teardown.
  • Adds deterministic refresh-task cleanup coverage.
  • Adds a live heap-growth regression test.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/common/authorizer.rs Adds refresh-task cancellation and test configuration.
src/common/recoverable/connection.rs Stops refresh during close and adds regression coverage.
tests/eventhubs_producer_memory.rs Adds lifecycle heap-trend testing.
Suppressed comments (2)

sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_producer_memory.rs:70

  • A missing Event Hub name also reports this regression test as passed without running any lifecycle. Preserve the fallback name if needed, but propagate failure when neither variable is configured.
    let eventhub = match env::var("EVENT_HUB_NAME") {
        Ok(eventhub) if !eventhub.is_empty() => eventhub,
        _ => match env::var("EVENTHUB_NAME") {
            Ok(eventhub) if !eventhub.is_empty() => eventhub,
            _ => return Ok(()),

sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_producer_memory.rs:76

  • Credential construction failure silently turns the live regression into a passing no-op. Since live mode was explicitly requested, propagate this error so an unusable test environment is visible.
    let credential = match DeveloperToolsCredential::new(None) {
        Ok(credential) => credential,
        Err(_) => return Ok(()),
    };

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread sdk/eventhubs/azure_messaging_eventhubs/src/common/authorizer.rs Outdated
Comment thread sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_producer_memory.rs Outdated
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
3 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@sagar0207 Sagar Patel (sagar0207) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core task-lifecycle fix looks sound. I found two concerns in the new live test and two documentation follow-ups.

Comment thread sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_producer_memory.rs Outdated
Comment thread sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_producer_memory.rs Outdated
Comment thread sdk/eventhubs/azure_messaging_eventhubs/src/common/authorizer.rs
Track live allocation bytes across sequential producer lifecycle tests.
Use warmups, block medians, and a noise-adjusted regression bound.
Gate a refresh credential and verify close releases the authorizer task.
Exercise the connection-owned authorizer with a gated refresh credential.
Expose only test-gated helpers for deterministic refresh timing and setup.
Use a terminal refresher state to synchronize startup with shutdown. Await task cancellation before close returns so the authorizer ownership cycle is released.
Use the accepted two-word spelling in the producer memory regression test so the pull request spell-check job can complete.
@j7nw4r
Johnathan W (j7nw4r) force-pushed the fix/eventhubs-producer-memory-leak branch 2 times, most recently from 035b9b7 to 47df38c Compare August 31, 2026 13:56
@j7nw4r
Johnathan W (j7nw4r) enabled auto-merge (squash) August 31, 2026 21:57
Use the accepted two-word spelling so the pull request spell-check job can complete.
Keep the authorization shutdown tests compatible with the transport parameter added on main.
@j7nw4r
Johnathan W (j7nw4r) merged commit 8aaeadc into Azure:main Sep 1, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Eventhub ProducerClient does not free memory on close()

4 participants