-
Notifications
You must be signed in to change notification settings - Fork 110
Implement a closeAll
utility to close multiple closeables
#3470
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
base: main
Are you sure you want to change the base?
Conversation
*/ | ||
@SuppressWarnings("PMD.CloseResource") | ||
public static void closeAll(AutoCloseable... closeables) throws CloseException { | ||
CloseException accumulatedException = null; |
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.
Why create a new exception type to accumulate, rather than setting it to the first exception thrown?
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.
That was how I initially tried to implement this but the compiler complained about "close() method can throw InterruptedException" when the close()
declares to throw Exception
.
Similar to the issue described here: TritonDataCenter/java-manta#322
fdb-extensions/src/main/java/com/apple/foundationdb/async/MoreAsyncUtil.java
Outdated
Show resolved
Hide resolved
fdb-extensions/src/main/java/com/apple/foundationdb/async/MoreAsyncUtil.java
Outdated
Show resolved
Hide resolved
if (logger.isWarnEnabled()) { | ||
logger.warn("Failed to close the throttled iterator", e); | ||
} | ||
// Do not rethrow. We are trying to close the runner and the exception should log all errors |
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.
Why the change here?
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 thought this would be a better fit to a usage like:
RepairValidationResults repairResults;
try (RecordRepairValidateRunner repairRunner = builder.buildRepairRunner(false)) {
repairResults = repairRunner.run().join();
}
// Handle results
Where a failure to close would disrupt the flow and cause the loss of already collected results.
But I am not too strongly opinionated about this.
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 seems only tangentially related to the purpose of the PR.
Also, I'm not sure I agree, I think you would want to do:
RepairValidationResults repairResults;
try (RecordRepairValidateRunner repairRunner = builder.buildRepairRunner(false)) {
repairResults = repairRunner.run().join();
// handle results
}
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.
Reverted to previous behavior. Also, since CloseException is now declared on the signature of the method, I moved the exception to its own top level class.
} | ||
|
||
/** | ||
* Exception thrown when the {@link CloseableUtils#closeAll} method catches an exception. |
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.
* Exception thrown when the {@link CloseableUtils#closeAll} method catches an exception. | |
* Exception thrown when the {@link #closeAll} method catches an exception. |
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.
Exception moved to separate file.
|
||
package com.apple.foundationdb.util; | ||
|
||
public class CloseableUtils { |
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.
Javadoc would be good, something short and sweet, like
public class CloseableUtils { | |
/** | |
* Utility methods to help interact with {@link AutoCloseable} things. | |
**/ | |
public class CloseableUtils { |
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.
Also, an API annotation. INTERNAL I think.
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.
Done x2
if (logger.isWarnEnabled()) { | ||
logger.warn("Failed to close the throttled iterator", e); | ||
} | ||
// Do not rethrow. We are trying to close the runner and the exception should log all errors |
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 seems only tangentially related to the purpose of the PR.
Also, I'm not sure I agree, I think you would want to do:
RepairValidationResults repairResults;
try (RecordRepairValidateRunner repairRunner = builder.buildRepairRunner(false)) {
repairResults = repairRunner.run().join();
// handle results
}
for (AutoCloseable closeable: closeables) { | ||
try { | ||
closeable.close(); | ||
} catch (Exception e) { |
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.
Since you are catch a generic exception, you are supposed to re-interrupt the current thread.
Also, probably worth a comment in the code here similar to the one on the PR explaining why we are converting it to a CloseException
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.
Done. I think there could be no case of InterruptedException
thrown from a close(), but it doesn't hurt to add a catch block.
Tech debt from the ThrottlingIterator work. Close multiple closeables and capture all exceptions.
Resolve #3465