Skip to content

Fixes transfers to File when append? is true #56

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

Merged
merged 3 commits into from
May 26, 2022

Conversation

KingMob
Copy link
Collaborator

@KingMob KingMob commented May 21, 2022

Fixes #23...I think.

I have no idea why it would have worked on Linux, but not a Mac. I believe append-mode for File transfers should have been broken for all platforms, except when "appending" to empty files.

The current fix calls .position() on the FileChannel to know where to start. Normally a fresh FC will be at 0, except in append mode, when .position() will always return the current size of the file.

This doesn't handle multiple writers correctly, since it never calls .position() again, but there's a lot more work to do to make byte-streams compatible with that assumption, so we're not tackling that here.

KingMob added 2 commits May 21, 2022 22:41
Move javac options to top-level in project.clj
Indentation changes
Add unit tests covering issue
@KingMob KingMob requested a review from slipset as a code owner May 21, 2022 15:23
@KingMob KingMob self-assigned this May 21, 2022
@arnaudgeiser arnaudgeiser requested review from arnaudgeiser and removed request for slipset May 21, 2022 18:35
(when (pos? n)
(recur (+ idx n)))))
;; .position() is 0 for normal mode, and the current size of the file in append mode
(loop [pos (.position fc)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Tests are passing without this modification.
Without a deep knowledge of byte-streams, I'm wondering whether we are acting at the right place here.
If I understand correctly, the position defines where on the ReadableByteChannel has to start, not on the ẀriteableByteChannel. [1]

But I might be totally wrong here.

[1] : https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/channels/FileChannel.html#transferFrom(java.nio.channels.ReadableByteChannel,long,long)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I’ll double-check, but the new tests were failing on my Mac. The original issue claimed it didn’t happen on Linux…is that your platform?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It’s the reverse about the position. It defines where in the FC to start writing, regardless of the FC’s current position. The RBC’s position advances normally as data is read.

If the transferFrom fn used the FC position, append mode would work by default.

That being said, I’m concerned that it may be platform-specific, because that means CI may miss a regression.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I reverted it, and my tests failed again.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I’ll double-check, but the new tests were failing on my Mac. The original issue claimed it didn’t happen on Linux…is that your platform?

Yes it is, but I got caught be your comment:

I believe append-mode for File transfers should have been broken for all platforms, except when "appending" to empty files.

So I confirm, it's working on Linux with and without your change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That’s crazy. I wonder if we discovered a Linux jdk bug. Which Java version did you test on?

the Java code quickly hands off to native code, nothing I saw would explain this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

❯ java -version
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment Temurin-17.0.1+12 (build 17.0.1+12)
OpenJDK 64-Bit Server VM Temurin-17.0.1+12 (build 17.0.1+12, mixed mode, sharing)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe the getChannel is behaving differently according to the platform.

[1] : https://github.com/clj-commons/byte-streams/blob/master/src/byte_streams.clj#L589

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, that's pretty likely, but I couldn't find anything online about it. I looked at the underlying FileChannelImpl class, and it dispatches a bunch to native-based FileDescriptors and FileDispatcher classes.

I can try more variations in the tests. Maybe fill it with data first, then close and reopen, to ensure we're not starting with an empty file.

Copy link
Collaborator

@arnaudgeiser arnaudgeiser left a comment

Choose a reason for hiding this comment

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

Perfect then!

Deprecate old test files
Remove empty byte-streams-reload-test
@KingMob KingMob merged commit edd7e5d into master May 26, 2022
@KingMob KingMob deleted the bugfix/transfer-append-true-broken branch May 26, 2022 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

{:append? true} is ignored on Mac, but not Linux
2 participants