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

Feature/capps2/successreturnvalue #1224

Merged
merged 46 commits into from
Jan 23, 2024
Merged

Conversation

agcapps
Copy link
Member

@agcapps agcapps commented Nov 22, 2023

Summary

Design review

On 13 November 2023, we (re)reviewed this PR. We decided that the extra information to the user was worthy of adding the feature.

@agcapps
Copy link
Member Author

agcapps commented Nov 22, 2023

There are several ways we could add a boolean return value to load, save, and loadExternalData. This is one.

Alternately, we could

  • make static bool axom::sidre::s_conduit_had_error into a member of DataStore
  • make setConduitSLICMessageHandlers and setConduitDefaultMessageHandlers instance methods, not static

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

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

This change in the PR would require a single global DataStore instance.

Is there a way to satisfy this issue without using global state?
E.g. registering a callback with conduit that modifies a local variable if there's an error? Or locally catching the conduit exception?

src/axom/sidre/core/DataStore.cpp Outdated Show resolved Hide resolved
@agcapps
Copy link
Member Author

agcapps commented Nov 27, 2023

This change in the PR would require a single global DataStore instance.

Not sure how it requires a single global DataStore instance.

Is there a way to satisfy this issue without using global state? E.g. registering a callback with conduit that modifies a local variable if there's an error? Or locally catching the conduit exception?

As I wrote, I would prefer storing the error flag as an instance variable on DataStore. The (possibly minor) obstacle is that DataStore::setConduitSLICMessageHandlers() and DataStore::setConduitDefaultMessageHandlers() are static. So currently, we could start out setting a per-DataStore flag on error, but a call to those two functions cannot touch anything that stores state in a DataStore.

@agcapps
Copy link
Member Author

agcapps commented Nov 27, 2023

After a spirited discussion on November 27 2023, the consensus was that we (Axom developers) don't like the static global variable. Within load() and allies, we will temporarily save the error handler, set it to default, and do the Conduit operations within a try/catch block. Afterward, restore the error handler.

This idea will let us be more specific when reporting what happened, and allows each DataStore to hold its own state.

I'll rework the PR to reflect this idea and resubmit for review.

@agcapps agcapps marked this pull request as draft November 27, 2023 22:54
@kennyweiss
Copy link
Member

This change in the PR would require a single global DataStore instance.

Not sure how it requires a single global DataStore instance.

What I meant was that if you had more than one DataStore instance, there would be no way to know which instance set the conduit_had_error variable. So I suppose I should have written that

This change in the PR would require likely be confusing if there was more than a single global DataStore instance.

@rhornung67 rhornung67 self-requested a review December 11, 2023 23:35
@agcapps agcapps marked this pull request as ready for review December 20, 2023 00:09
@agcapps
Copy link
Member Author

agcapps commented Dec 21, 2023

@nselliott , @kennyweiss , @cyrush , @rhornung67 , I'd appreciate your reviews. Thanks.

Copy link
Contributor

@nselliott nselliott left a comment

Choose a reason for hiding this comment

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

Thanks Arlie. Approving with one comment on a small thing that should be fixed.

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

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

Thanks @agcapps

Looks good overall.
My main question relates to resetting the error flags -- whose responsibility is it and when does it occur?

src/axom/sidre/core/Group.cpp Show resolved Hide resolved
Comment on lines 2163 to 2165
SLIC_ERROR(SIDRE_GROUP_LOG_PREPEND << "Invalid protocol '" << protocol
<< "' for save with hdf5 handle.");
}
Copy link
Member

Choose a reason for hiding this comment

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

As above, the code should return false if an invalid protocol was passed.
Please also check the other similar cases.
(Note SLIC_ERROR can be configured to not call exit).

Comment on lines +101 to +104
void appendToConduitErrors(const std::string& mesg) const
{
m_conduit_errors = m_conduit_errors + "\n" + mesg;
};
Copy link
Member

Choose a reason for hiding this comment

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

Would a std::list<std::string> (or similar) be better than appending strings on the fly?

A benefit would be that DataStore would not need to explicitly manage a separate bool for m_conduit_error_occurred -- it could instead be m_conduit_errors.empty().

@@ -1808,7 +1808,7 @@ TEST(sidre_group, save_restore_empty_datastore)
for(const auto& protocol : protocols)
{
const std::string file_path = file_path_base + protocol;
ds1->getRoot()->save(file_path, protocol);
EXPECT_TRUE(ds1->getRoot()->save(file_path, protocol));
Copy link
Member

Choose a reason for hiding this comment

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

Are there any cases that test the EXPECT_FALSE path?
E.g. by setting slic::disableAbortOnError()

/*!
* \brief Disables aborts on error messages for the current active logger.
*
* \note this is equivalent to calling slic::setAbortOnError( false )
* \post slic::isAbortOnErrorsEnabled() == false.
* \pre slic::isInitialized() == true
*/
void disableAbortOnError();

Copy link
Member Author

Choose a reason for hiding this comment

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

There are no cases that test EXPECT_FALSE, at this point. I should, indeed, try that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added tests that use EXPECT_FALSE.

Comment on lines 1832 to 1833
m_ds->setConduitErrorOccurred(true);
m_ds->appendToConduitErrors(e.message());
Copy link
Member

Choose a reason for hiding this comment

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

I might be missing it, but where are the errors cleared?

Is that the user's responsibility? If so, is it documented and/or exercised in the sidre tests and examples?

Copy link
Member Author

Choose a reason for hiding this comment

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

The user should clear errors as and when the user sees fit. I'm in the process of adding tests and documentation.

@agcapps
Copy link
Member Author

agcapps commented Jan 9, 2024

Thanks @agcapps

Looks good overall. My main question relates to resetting the error flags -- whose responsibility is it and when does it occur?

The user has the responsibility to reset any error flags, or not, as needed. Most times, the user will probably detect the error and abort the simulation. More sophisticated error-handling is up to the user.

@agcapps agcapps merged commit b89d583 into develop Jan 23, 2024
12 checks passed
@agcapps agcapps deleted the feature/capps2/successreturnvalue branch January 23, 2024 05:47
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.

Group::load() and save() should return a success value
5 participants