Skip to content

CAMEL-24195: camel-aws2-s3 - Fix StreamUploadProducer race condition and timeout task exception handling#24872

Merged
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24195
Jul 17, 2026
Merged

CAMEL-24195: camel-aws2-s3 - Fix StreamUploadProducer race condition and timeout task exception handling#24872
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24195

Conversation

@davsclaus

Copy link
Copy Markdown
Contributor

Summary

Claude Code on behalf of davsclaus

Fixes two concurrency bugs in AWS2S3StreamUploadProducer:

  • Race condition: uploadAggregate was read and mutated outside the lock in processWithoutTimestampGrouping() (lines 181-184). The timeout task acquires the lock and can set uploadAggregate = null, so the main thread could dereference a null reference (NPE). Fix: moved the reads inside a lock block.

  • Timeout task exception handling: StreamingUploadTimeoutTask.run() did not catch exceptions from uploadPart()/completeUpload(). Since ScheduledExecutorService.scheduleAtFixedRate silently cancels all future executions when the task throws an uncaught exception, any S3 API error would permanently disable the timeout flush mechanism. Fix: wrapped the upload calls in try-catch to log and continue.

Test plan

  • Module builds successfully (mvn install -DskipTests)
  • Existing integration tests still pass
  • Race condition fix verified by code inspection — the unprotected read window is now under the lock
  • Exception handling verified by code inspection — timeout task catches and logs errors instead of propagating

🤖 Generated with Claude Code

…ption handling in StreamUploadProducer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus
davsclaus requested review from orpiske and oscerd July 17, 2026 18:54
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@gnodet gnodet 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.

Claude Code on behalf of gnodet

CAMEL-24195: StreamUploadProducer race condition and timeout task exception handling — LGTM

Two well-targeted concurrency fixes:

1. Timeout task exception handling ✅

Wrapping uploadPart()/completeUpload() in try-catch inside StreamingUploadTimeoutTask.run() is the right call. ScheduledExecutorService.scheduleAtFixedRate silently cancels all future executions when the task throws an uncaught exception — so any transient S3 API error would permanently disable the timeout flush mechanism. Now it logs a warning and continues.

Design note: uploadAggregate = null runs even on failure, which means the current aggregate's data is discarded on error. This is a reasonable tradeoff — in the original code, the exception would kill the timeout task entirely, so the data would be lost anyway (stuck in memory forever with no future flushes). The new behavior is strictly better: current aggregate lost, but future timeout flushes keep working.

If retry semantics are ever needed, uploadAggregate = null could move inside the try (only null on success), but that would require careful handling of partial state (e.g., uploadPart succeeded, completeUpload failed → retrying uploadPart could duplicate parts).

2. Race condition fix ✅

The initial maxRead computation in processWithoutTimestampGrouping() now runs under the lock. I verified that subsequent uploadAggregate accesses inside the while loop are already protected by lock.lock(), so this closes the only unprotected window. There's a minor TOCTOU between releasing this lock and the first loop iteration (the timeout task could null uploadAggregate), but that only results in a slightly suboptimal maxRead on one iteration — not a correctness issue since the loop re-acquires the lock before accessing the aggregate.

Clean, minimal, well-scoped fix.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-aws/camel-aws2-s3

🔬 Scalpel shadow comparison — Scalpel: 10 tested, 29 compile-only — current: 10 all tested

Maveniverse Scalpel detected 39 affected modules (current approach: 10).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 10 modules (1 direct + 9 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (10)
  • camel-aws2-eventbridge
  • camel-aws2-s3
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-launcher-container
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (39 modules)
  • Camel :: AWS2 Eventbridge
  • Camel :: AWS2 S3
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@davsclaus davsclaus added this to the 4.22.0 milestone Jul 17, 2026
@davsclaus davsclaus added the bug Something isn't working label Jul 17, 2026
@davsclaus davsclaus self-assigned this Jul 17, 2026
@davsclaus
davsclaus merged commit d8be2da into main Jul 17, 2026
5 checks passed
@davsclaus
davsclaus deleted the fix/CAMEL-24195 branch July 17, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working components components-aws

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants