Fix ThreadSanitizer data races between bundle processing and async background writer closing in FileBasedSink and WriteFiles - #39458
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment |
|
Assigning reviewers: R: @chamikaramj for label java. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
|
R: @sjvanrossum |
|
Stopping reviewer notifications for this pull request: review requested by someone other than the bot, ceding control. If you'd like to restart, comment |
|
If I understand correctly, Alternatively, attempt a CAS on |
f333cb1 to
05f9167
Compare
…ckground writer closing in FileBasedSink and WriteFiles
05f9167 to
32eea5d
Compare
|
@sjvanrossum It's not only open() and async close(), it is also racing between write() and async close. take a look at this approach. |
|
R: @sjvanrossum |
Summary
Fixes ThreadSanitizer data races during asynchronous file closing in
WriteFiles/FileBasedSinkand an OS file-descriptor race inTFRecordSchemaTransformProviderTest.Root Cause
FileBasedSink/WriteFiles):FileBasedSink.Writerinstances are written to on the bundle processing thread and closed asynchronously viaMoreFutures.runAsync. Lacking a release-acquire memory barrier between threads, TSAN reported cross-thread data races on:FileBasedSink.Writer.close()V(FileBasedSink.java:1066readingchannel.isOpen()vs.Writer.open()atFileBasedSink.java:993writingchannel = factory.create(...)).CRC32.getValue()J(reading GZIP checksums duringclose()vs.crc.update(...)duringwrite(value)).TFRecordSchemaTransformProviderTest): An unclosedFileInputStreamcaused a syscall race when the JDK background Cleaner thread closed the unreferenced file descriptor during test execution.Solution
readyToClose): Added anAtomicBoolean readyToClosehandoff toFileBasedSink.Writer. CallingreleaseForBackgroundClose()(readyToClose.set(true)) before spawning the async task and callingreadyToClose.get()at the start ofclose()/cleanup()ensures thatopen(),write(), and all stream mutations happen-before background closing.FileInputStreaminTFRecordSchemaTransformProviderTest.runTestWritein a try-with-resources block for deterministic closure.Testing
TFRecordSchemaTransformProviderTest(--config=tsan-chlor) pass cleanly with zero data race reports.Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, commentfixes #<ISSUE NUMBER>instead.CHANGES.mdwith noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)
See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.