-
Notifications
You must be signed in to change notification settings - Fork 27
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
Slic open before flush #1387
Slic open before flush #1387
Conversation
…oblematic unit test again
54de589
to
4a3cc79
Compare
…instances" This reverts commit c9b27c8.
This PR is ready for review, confirmed with @gberg617 that it is working for their use case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @bmhan12 Looks good!
* | ||
* \note The constructed std::ofstream will open and associate a file with | ||
* the stream the first time GenericOutputStream is flushed with at | ||
* least one buffered message. Use this constructor | ||
* to avoid empty file creation if GenericOutputStream is not appended | ||
* to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This note
(and the one at new line 82) is hard to understand. Please rephrase. Consider dropping the first sentence and changing the second to something like "Use this constructor to avoid creating an empty file if this GenericOutputStream never gets a message."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working this through, Brian.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @bmhan12 !
Please also update the RELEASE_NOTES
about this change.
std::ostringstream* oss = dynamic_cast<std::ostringstream*>(m_stream); | ||
if(oss != nullptr) | ||
{ | ||
std::string buffer = oss->str(); | ||
if(!buffer.empty()) | ||
{ | ||
delete m_stream; | ||
m_stream = new std::ofstream(m_file_name); | ||
(*m_stream) << buffer; | ||
m_opened = true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting approach!
It took me a moment to figure out why the delete/new is necessary.
Could you please add a brief comment that we're converting from the original ostringstream
to an ofstream
and writing the former's contents to the latter?
|
||
EXPECT_EQ(with_fmt_buffer.str(), "Test"); | ||
|
||
// Cleanup generated files (not working Windows) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it known that this doesn't work on Windows?
I didn't see an issue for this -- if we don't have one, can you please create one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see an issue for this -- if we don't have one, can you please create one?
Opened an issue here: #1415
I didn't dive too deep into why it wasn't working on Windows for this specific case.
More generally though, there are multiple places where we call removeFile
in the code but don't check the return value/check if file is really deleted.
This PR:
Explores an alternative way to create Slic log streams to files. With the current Slic approach, files must be opened/created when the stream object is constructed. If no messages are logged, the file remains empty. If there is an error and Slic tells MPI to abort, all ranks will attempt to flush, with files remaining empty if the rank could not flush before the non-collective abort call and/or no messages have been logged on that rank.
Constructors were added to
GenericOutputStream
/LumberjackStream
/SynchronizedStream
that take in astd::string
that is parsed and interpreted asstd::cout
,std:cerr
, or a file name. In the case of a filename, the file is not opened until slic flushes and the stream has at least one message logged. This is done inLumberjackStream
/SynchronizedStream
by default constructing anstd::ofstream
object (no file has been opened yet), and delaying theopen(filename)
call until flushing. This is done inGenericOutputStream
by initially constructing anstd::ostringstream
to buffer the messages in memory, and turning thestd::ostringstream
into astd::ofstream
file when flushing.- While these constructors work, I am not sure if it's the best way of addressing the current lack of file support in Slic. These(Resolved. Can add getter method later tostd::string
constructors take ownership ofstd::ostream
from the user, which can be limiting if you want access to both thestd::ostream
object and the open-before-flush file behavior. In previous discussions, @gberg617 suggested adding getter methods to the in-memory messages storage (e.g. Lumberjack object in LumberjackStream, std::vector of messages in SynchronizedStream), so developers could take that information and create their own behavior. This would allow user-access to thestd::ostream
object and the open-before-flush file behavior with some effort.std::ostream
object if needed for access when using string constructors).