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

BinaryFileStream should not truncate on flush #53

Closed
kurtkilpela opened this issue Mar 4, 2022 · 22 comments
Closed

BinaryFileStream should not truncate on flush #53

kurtkilpela opened this issue Mar 4, 2022 · 22 comments
Assignees

Comments

@kurtkilpela
Copy link
Member

In f219c5e, BinaryFileStream>>#flush was updated to truncate the file to the current position. This was implemented as Rowan did not seem to truncate existing files when writing packages out to disk.

This should be reverted. If there is still an issue where package files aren't truncated, Rowan should be updated to properly truncate.

@kurtkilpela kurtkilpela self-assigned this Mar 4, 2022
@dalehenrich
Copy link
Member

out of curiosity ... what would be the proper way to truncate files?

@kurtkilpela
Copy link
Member Author

Sending #truncate to the stream would be sufficient.

@dalehenrich
Copy link
Member

dalehenrich commented Mar 4, 2022 via email

@dalehenrich
Copy link
Member

... should #close do a truncate ... instead of flush?

@kurtkilpela
Copy link
Member Author

I imagine the pattern would be stream flush; truncate; close. The problem with having truncate occur automatically, is that you may not actually want it. It is hard to work around if it happens automatically.

You could open a file stream, seek to a record in the middle of a file, write a few bytes to change the record, and then close it. If we automatically truncate the file, you'd always have to read the full file in, make the changes, and then write the whole file out. That doesn't scale well.

(Alternatively, in the Rowan case, you could truncate after opening the file.)

@martinmcclure
Copy link
Member

In Pharo, sending truncate to a file stream appears to truncate the file to position 0; i.e. wipes the entire contents. So you wouldn't want to do that after writing contents you wanted to keep.

If you want to write an entire file, possibly creating it but not keeping any previous contents, the best way to do that is to specify the truncate option when opening the file. This results in the open() system call having the O_TRUNC flag set, and may not yet be supported by FileSystemGs (but should be at some point).
Alternatively, truncating after opening, as Kurt suggests, should work.

@kurtkilpela
Copy link
Member Author

Yeah, I saw that behavior in Pharo. It wasn't yet clear to me that that was correct behavior. I suppose we will take the semantics since we are porting FileSystem. They do have a second selector #truncate: which allows you to truncate to any position.

The simplest thing would be to just truncate immediately after opening the file.

@dalehenrich
Copy link
Member

dalehenrich commented Mar 4, 2022 via email

@kurtkilpela
Copy link
Member Author

Pharo FileReference doesn't have an #openAppend. Pharo's File class does have an #openForAppend.

It would be possible for us to add several open methods. Or we could have an open that takes a FileOpeningOptions instance (which is the direction we've been heading.)

@martinmcclure
Copy link
Member

The unary selector #truncate truncating to any position but zero would be quite unexpected behavior, so I think that Pharo's behavior is the expected one.

For opening options I think there should be #openFoo for only the most common options, for everything else use a FileOpeningOptions. Maybe something like myFileReference openWithOptions: FileOpeningOptions write truncate.

@kurtkilpela
Copy link
Member Author

I find it a little weird that #truncate doesn't truncate to the current position for a Stream. I would agree that a send of #truncate to an instance of UnixFileDescriptor doing anything other than truncate to zero would be weird.

@dalehenrich
Copy link
Member

dalehenrich commented Mar 4, 2022 via email

@dalehenrich
Copy link
Member

dalehenrich commented Mar 4, 2022 via email

@martinmcclure
Copy link
Member

It seems odd to me to have streams respond to truncate at all, it has no obvious meaning to me. Maybe truncateToHere as a shortcut for stream truncateTo: stream position, but there's the Pharo precedent to worry about.

@dalehenrich
Copy link
Member

I suppose defaulting to Pharo behavior is not a bad way to go for truncate, while openWithOptions: (with short cuts) meets our needs and is an intentional departure from Pharo anyway ...

@kurtkilpela
Copy link
Member Author

Matching the Pharo behavior is the best answer. Pharo does have a #truncate: which allows you to truncate to a specific length.

@kurtkilpela
Copy link
Member Author

kurtkilpela commented Oct 27, 2022

Added AbstractFileReference>>#truncatedWriteStreamDo:. Rowan's pattern is to use #writeStreamDo:. This new selector will truncate the file before evaluating the argument and should be a sufficient replacement for Rowan. See 0cac5ba.

Once Rowan has swapped to #truncatedWriteStreamDo:, #flush can stop truncating the file to the current position.

@kurtkilpela
Copy link
Member Author

Note to self: sending #truncate to a stream, results in truncating the file to position 0, not the current position.

@kurtkilpela
Copy link
Member Author

Per conversation with Dale, remove #truncatedWriteStreamDo: and #appendingWriteStreamDo:. Instead, the stream will just be created in appending mode. In the case of truncation, the file will be truncated as the first action in the #writeStreamDo: block argument.

@kurtkilpela
Copy link
Member Author

kurtkilpela commented Jan 31, 2023

844685f removes the previous send of #truncate in #flush. See #105

@kurtkilpela
Copy link
Member Author

c0282f0 removes #truncatedWriteStreamDo: and '#appendingWriteStreamDo:`.

Rowan will send #truncate to the stream as necessary.

@kurtkilpela
Copy link
Member Author

6fe072f ensures files are truncated to a length of zero bytes when an associated write stream receives #truncate.

dalehenrich pushed a commit to GemTalk/Rowan that referenced this issue Feb 8, 2023
… worked around this issue but truncating to current stream position on #flush.

See: GemTalk/FileSystemGs#53
dalehenrich pushed a commit to GemTalk/Rowan that referenced this issue Feb 8, 2023
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

No branches or pull requests

3 participants