Investigate MANTA close() function is working as expected.
Background:
Mex servers are downloading Manta object to read via inputStream. Once the inputStream is opened and read a few bytes on the head of the file, it closes using close() function. However, the traffic to MANTA seems not been closed, and the application will try to open the same file using inputStream again and close it a few times.
Concerns Raised:
After inputStream close(), download traffic is triggered for a long time, please analyze the close() function is working as expected.
abortConnection() seems to be deprecated soon, please confirm if OK to use in production level.
Test Application:
// test code
try (InputStream is = client.getAsInputStream(mantaFile, header)){
Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name());
for (int i=0; i<1; i++) {
//while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
//is.abortConnection();
//is.close();
}
////connection is not closed//////
Analysis:
The significant difference between close() and abortConnection() is that one permits reusing underlying streams once closing the stream is attempted while the other doesn't.
Historically they both implemented IOUtils.closeQuietly() which ended up violating the API definition on how streams are handled in Java and the reason why these changes were made in #485 but ever since that method got deprecated, we had to adopt alternate choices.
Reasons for that being as follows:-
The vast majority of closable(s) fell into two categories but I only mentioned the category that's relevant to this issue:
A readable; InputStream or Reader (in our case InputStream). The vast majority of implementations of any such streams never actually throw IOException, so the close() method does nothing of any use whatsoever. closeQuietly lets you dodge the need to formally handle the wont-actually-ever-happen IOException, but this is rarely needed as the close method is usually near the read methods, which can and do throw IOException.
So what #485 essentially did was to pop the close() call into the try block.
It seems the customer wants to prematurely terminate connections to their server while downloading objects(s).
Q: Why abortConnection() works ?
Ans: Closables.close() does have a realistic use case (to facilitate the throwing of the first exception, and not the 'followup' usually less useful exception thrown by the close method once a write/read has already failed). This essentially means when the deprecated method is called its prevents reusing the underlying connection, that has been attempted to terminate, which essentially means there are no more attempts allowed to attempt reading the underlying stream once abortConnection() is called.
Solution:
After much deliberation undeprecating abortConnection() is a wise move given customer's usage of downloading objects.
Reconfigured close to use underlying EofSensorInputStream.close() which has a better implementation call since most usages seem to be pertinent to that condition.
Introduced null check which was missing earlier and refactored code based on how we handle streams post Java 7. For more details visit the references listed below.
Investigate MANTA close() function is working as expected.
Background:
Mex servers are downloading Manta object to read via inputStream. Once the inputStream is opened and read a few bytes on the head of the file, it closes using close() function. However, the traffic to MANTA seems not been closed, and the application will try to open the same file using inputStream again and close it a few times.
Concerns Raised:
Test Application:
Analysis:
The significant difference between
close()
andabortConnection()
is that one permits reusing underlying streams once closing the stream is attempted while the other doesn't.Historically they both implemented
IOUtils.closeQuietly()
which ended up violating the API definition on how streams are handled in Java and the reason why these changes were made in #485 but ever since that method got deprecated, we had to adopt alternate choices.Reasons for that being as follows:-
The vast majority of closable(s) fell into two categories but I only mentioned the category that's relevant to this issue:
Q: Why abortConnection() works ?
Ans: Closables.close() does have a realistic use case (to facilitate the throwing of the first exception, and not the 'followup' usually less useful exception thrown by the close method once a write/read has already failed). This essentially means when the deprecated method is called its prevents reusing the underlying connection, that has been attempted to terminate, which essentially means there are no more attempts allowed to attempt reading the underlying stream once abortConnection() is called.
Solution:
After much deliberation undeprecating
abortConnection()
is a wise move given customer's usage of downloading objects.Reconfigured close to use underlying
EofSensorInputStream.close()
which has a better implementation call since most usages seem to be pertinent to that condition.Introduced
null
check which was missing earlier and refactored code based on how we handle streams post Java 7. For more details visit the references listed below.References:
Oracle Docs on try-resource-close.
Apache docs listing IOUtils as deprecated.
blog post on closing-streams-in-java.