aws / aws/aws-sdk-java-v2

S3: getObject, ResponseInputStream close not working as expected.

Offen
#2,117 6 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug p3
Vorherrschende Sprache
Java
Sterne
2.6k
Forks
1k
Ø Merge
2 T. 9 Std.
Gemergte PRs (30 T.)
51

Beschreibung

## Describe the bug
When you invoke close on ResponseInputStream from the getObject before you reach the end of the data. The stream will not immediately(/within reasonable time) close on big files.

## Expected Behavior
When invoking close on an ResponseInputStream you would expect a close within at least a few seconds.

## Current Behavior
It does not close until it did a complete read of the stream internally. (this seems related to connection recycling internally).

## Steps to Reproduce
- Upload a big file to S3 atleast a 1-2 gb to observe the issue on fast internet connection
```
var r = client.getObject(c -> {
c.bucket(bucket).key(key).versionId(versionId);
});
r.read(new byte[1024]); // just to make sure we actually opened the resource and did something.
r.close(); // now you have to wait until the entire file is read by the close internally.
```

## Possible Solution
- The internal handler closes the stream immediately, possibly by simply closing the underlying connection.
- It could make a decision based on the remaining bytes to read to make the impact less significant on big files (e.g. if remaining > 1 MB close connection, otherwise consume).

## Context
I was trying to create a test case for a wrapper i created for handling network related issues (e.g. connection reset). Where i would simply track the position in the stream and use a range request when the connection fails, to continue the stream transparently.
When testing it by creating a wrapper around the ResponseInputStream that throws randomly a IO exception i noticed the extreme delay when closing the ResponseInputStream.

## Workaround
```
var r = client.getObject(c -> {
c.bucket(bucket).key(key).versionId(versionId);
});
r.read(new byte[1024]); // just to make sure we actually opened the resource and did something.
r.abort(); // <<< Workaround, but this is not part of a InputStream contract
r.close(); // now the connection closes almost immediately.
```
## Your Environment

* AWS Java SDK version used: 2.15.14
* JDK version used: 11
* Operating System and version: windows 10

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem S3 getObject-Pfad und dem im Issue beschriebenen Verhalten beim Schließen und Abbrechen von ResponseInputStream. Reproduziere das Problem mit einem großen S3-Objekt, indem du einen kleinen Puffer liest und close aufrufst, bevor das Ende erreicht ist, und verfolge anschließend das interne Verhalten beim Wiederverwenden der Verbindung. Als abgeschlossen gilt die Untersuchung, wenn close innerhalb von angemessenen wenigen Sekunden zurückkehrt, ohne abort zu benötigen oder das verbleibende Objekt lesen zu müssen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
aws, java
Bereich
api, cloud
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.