Uh oh!
There was an error while loading. Please reload this page.
io error handling design - #770
Conversation
sinistersnare
commented
Jan 29, 2015
-1 this kinda disagrees with Rust's RAII in my opinion. |
untitaker
commented
Jan 29, 2015
I like the ideas in this, but am not sure at all if this should be applied to all kinds of Writers. I do think it is absolutely necessary for some Writers to force explicit errorhandling on close() |
untitaker
commented
Jan 29, 2015
Previous discussion: https://github.com/rust-lang/rfcs/pull/576/files#r23805711 |
untitaker
commented
Jan 29, 2015
@sinistersnare I think the link above explains why RAII doesn't work for some kinds of Writers. |
kjpgit
commented
Jan 29, 2015
@sinistersnare RAII is a great way to release resources and that's what we're doing. An unflushed buffer in BufferWriter is being released. But what we're not doing is attempting to create new resources, e.g. on the filesystem, with no way to relay errors because we don't want to panic in a destructor. |
mahkoh
commented
Jan 29, 2015
-1 The current way works well in practice which means that this RFC is a serious step backwards for most users. |
sinistersnare
commented
Jan 29, 2015
I feel like the sort of random panics that are trying to be prevented in this RFC are still in Rust in a few ways. For example, Basically, I do not think that the correctness benefit is greater than the ergonomic loss. However, if there is a resounding yes to this proposal, I am no language designer (I wish I was, but alas), so I wont be too upset it if was accepted. Thanks for the reading, I am currently procrastinating homework, but I will try to read that later :) |
untitaker
commented
Jan 29, 2015
I agree with you, but IMO it's less problematic with println, because if you want to explicitly handle errors, stdout.write is not too low-level. I suppose ideally Rust would have an API with explicit error checks, and one for the common usecase which panics on edgecases. |
Diggsey
commented
Jan 29, 2015
There was a discussion about the same issue but for C++: the ideal semantics IMO, would be for the guard to flush and close the underlying stream iff it exits the scope normally, rather than as the result of a panic and stack unwinding. Errors from close result in a panic (to avoid this, close must be called explicitly and the errors handled) The problem is that it's impossible to implement this correctly using only a library method such as "is thread panicking" to be called from the destructor to determine whether to close() or not, because even during a panic, a guard within a destructor can exit scope normally. Possible implementation: add a "Closable" trait. The compiler will automatically insert calls to "close()" when a stack object implementing that trait leaves scope normally (ie. not as part of unwinding). For Closable objects constructed on the heap, it is up to the owner to call "close" explicitly. For example, Box<T: Closable> should itself implement Closable and forward on the calls as expected. |
kjpgit
commented
Jan 29, 2015
Thanks @Diggsey for that comment about a guard in a destructor. I added a note "Note that this can give a false negative" in the RFC, but I am doing the reverse logic as what you are suggesting. And +1 to your comment. I'm trying to decide if it's backwards compatible with my proposal. We could say implicit drop has undefined behavior if you didn't call close(), and leave it at that until Closeable happens, and then it changes to defined behavior - nothing happens unless it left scope normally, in which case it is closed, but then that could in theory cause panics in code that didn't before. |
kjpgit
commented
Jan 29, 2015
@Diggsey the way to stop Closeable would be to explicit drop(myfile), right? In case you wanted to be future proof. e.g. in pseudocode: do_something_with(&my_file) I'm assuming there is potentially a use case somewhere where you don't want to flush and close the buffered file in some circumstance. |
Diggsey
commented
Jan 29, 2015
@kjpgit Yeah, anything which consumes the Closable would prevent the compiler from emitting calls to close or drop as usual. The drop method itself shouldn't call close either, so that gives you a way to avoid it. I think adding Closeable later can be made backwards compatible, as long as a few conditions hold:
|
kjpgit
commented
Jan 29, 2015
@Diggsey I'm still confused how the automagic scoped_close() method is prevented. drop is literally an empty function, and we want to move file objects around to new scopes. So both the close() method itself needs a way to take ownership, close resources, and drop without having the scope_close() called again. Same with the example code I did earlier. There seems to be a more magical drop() needed. |
Diggsey
commented
Jan 30, 2015
Sorry I phrased that badly, when I said "drop" shouldn't call close, I meant it should be defined to not call close, not that it will already behave that way under the current implementation. |
kjpgit
commented
Jan 30, 2015
@Diggsey I think the Closeable will unfortunately cause panics with people who are trying not to write panicing code. E.g. try!(my_file.close()); Is obviously designed not to panic, but if Closeable is the default, if my_file fails and try! tries to return an error, and then my_file2 also fails autoclose, it will cause a panic where there shouldn't have been one. |
kjpgit
commented
Jan 30, 2015
@mahkoh "The reason why rust "somewhat" works today is because Rust's stdout |
Diggsey
commented
Jan 30, 2015
@kjpgit That's a difficult case - I'm starting to think that explicit close might be the best we can do. In combination with a lint it shouldn't be too bad. |
mahkoh
commented
Jan 30, 2015
@kjpgit: I consider panic quite useless and would not mind having it replaced by abort. Either way, you wouldn't use println! and friends outside of toy programs. |
mzabaluev
commented
Feb 25, 2015
I think the use case to have |
mzabaluev
commented
Feb 25, 2015
To clarify the comment above: I support the need for |
mzabaluev
commented
Feb 27, 2015
Making the types that need explicit |
aturon
commented
Mar 20, 2015
When we discussed this (fairly extensively) during IO reform, one of the basic questions was: what errors can you receive when trying to close a file that would not also arise by flushing it? That is, in what circumstances is calling cc @sfackler |
gkoz
commented
Mar 20, 2015
It's not a file... but a block mode cipher that's had an incomplete block of data written to it can't |
aturon
commented
Mar 20, 2015
@gkoz That's an interesting example, but it's not clear why |
gkoz
commented
Mar 20, 2015
@aturon Generally, it could work but when doing foreign library bindings (e.g. rust-openssl) it's not always possible. Or rather I'd say openssl actively refuses to play by Rust's rules ;) (We could catch the case of unaligned end of data in block modes relatively easily, tracking padding would require some effort and overhead, the authentication case? well...) Isn't it also a bit odd for |
gkoz
commented
Mar 20, 2015
To rephrase the last point, is it appropriate for |
kjpgit
commented
Mar 20, 2015
@aturon I'm confused. Are you inquiring about something besides what the close(2) NOTES section on linux talks about? |
mzabaluev
commented
Mar 21, 2015
The implementations of |
alexcrichton
commented
Jul 16, 2015
This RFC is now entering its week-long final comment period. My personal feelings on this RFC is that while it may certainly be desirable to have a |
aturon
commented
Jul 16, 2015
I agree with @alexcrichton; while there is a hypothetical need for this functionality, I think we have much bigger fish to fry with respect to IO, and I would prefer to wait on this until there is a more clear need for the functionality. It's worth noting that, especially with the forthcoming |
kjpgit
commented
Jul 16, 2015
I'm not sure what bigger fish to fry there are than making sure data isn't On Thu, Jul 16, 2015 at 11:03 AM, Aaron Turon notifications@github.com
|
mzabaluev
commented
Jul 16, 2015
I, too, think it a pity that one needs more than the standard library to use the basic file functionality on POSIX systems with a degree of reliability that the developers are accustomed to (no hard write-through guarantee, but a number of easy-to-detect errors not going unreported either). Hiding a potentially blocking operation in the destructor without an explicit way to invoke it or drain the output buffer (files only have |
alexcrichton
commented
Jul 16, 2015
I think this is a bit hyperbolic to say, so it may not be 100% faithful to this RFC. We will always have primitives close themselves on drop, so receiving an error from the
I'm not sure this is a line of reasoning we can follow too far though as it's unclear how many possible designs there are in this space. As I mentioned above, we're always going to call It seems like we will fundamentally always close I/O objects on drop, and then we will also very likely provide the ability to manually close an object to see if any errors arise. It will always be an opt-in to seeing the error on |
tbu-
commented
Jul 24, 2015
The problem is that right now there isn't an obvious way to write to a file and check whether an error has occured. That's pretty fundamental if you ask me. To hyperbolize this point a bit, not checking the return value of I fail to understand how you can brush this off as a minor issue. :( |
untitaker
commented
Jul 24, 2015
As far as I understand On Fri, Jul 24, 2015 at 02:59:20PM -0700, tbu- wrote:
|
tbu-
commented
Jul 25, 2015
@untitaker |
main--
commented
Jul 25, 2015
@untitaker@tbu- As there seems to be confusion regarding Rust's current behavior:
|
alexcrichton
commented
Jul 29, 2015
The consensus of the libs team this week was to close this RFC. While it's something we may want to add to the standard library in the future, with the addition of Thanks again for the RFC @kjpgit! |
thanks for reading!