Skip to content

Commit

Permalink
Issue #9336 - remember ContentSources to fail from ChunksPart
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <[email protected]>
  • Loading branch information
lachlan-roberts committed Feb 15, 2023
1 parent b9b26e2 commit 5775887
Showing 1 changed file with 28 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -120,7 +121,7 @@ public static String generateBoundary(String prefix, int randomLength)
*/
public abstract static class Part implements Closeable
{
private static final Throwable CLOSE_EXCEPTION = new StaticException("Closed");
static final Throwable CLOSE_EXCEPTION = new StaticException("Closed");

private final String name;
private final String fileName;
Expand Down Expand Up @@ -347,6 +348,9 @@ public String toString()
public static class ChunksPart extends Part
{
private final List<Content.Chunk> content;
private final List<Content.Source> contentSources = new ArrayList<>();
private final AutoLock lock = new AutoLock();
private boolean closed = false;

public ChunksPart(String name, String fileName, HttpFields fields, List<Content.Chunk> content)
{
Expand All @@ -358,17 +362,36 @@ public ChunksPart(String name, String fileName, HttpFields fields, List<Content.
@Override
public Content.Source newContentSource()
{
List<Content.Chunk> newChunks = content.stream()
.map(chunk -> Content.Chunk.from(chunk.getByteBuffer().slice(), chunk.isLast()))
.toList();
return new ChunksContentSource(newChunks);
try (AutoLock l = lock.lock())
{
if (closed)
return null;
ChunksContentSource newContentSource = new ChunksContentSource(content.stream()
.map(chunk -> Content.Chunk.from(chunk.getByteBuffer().slice(), chunk.isLast()))
.toList());
contentSources.add(newContentSource);
return newContentSource;
}
}

@Override
public void close()
{
List<Content.Source> contentSourcesToFail = null;
try (AutoLock l = lock.lock())
{
closed = true;
if (!contentSources.isEmpty())
{
contentSourcesToFail = new ArrayList<>(contentSources);
contentSources.clear();
}
}

super.close();
content.forEach(Content.Chunk::release);
if (contentSourcesToFail != null)
contentSourcesToFail.forEach(cs -> cs.fail(CLOSE_EXCEPTION));
}

@Override
Expand Down

0 comments on commit 5775887

Please sign in to comment.