From 6e3684b5803cc673a9eed2978ea5689aca2ebc24 Mon Sep 17 00:00:00 2001 From: pratik Date: Tue, 21 Oct 2025 16:19:06 -0500 Subject: [PATCH] write to disk --- .../service/ChunkedUploadService.java | 20 ++++++++++++++----- src/main/resources/application.properties | 10 ++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/cfdeployer/service/ChunkedUploadService.java b/src/main/java/com/cfdeployer/service/ChunkedUploadService.java index 15f2c81..4359a18 100644 --- a/src/main/java/com/cfdeployer/service/ChunkedUploadService.java +++ b/src/main/java/com/cfdeployer/service/ChunkedUploadService.java @@ -61,16 +61,26 @@ public class ChunkedUploadService { fileType, fileState.getTotalChunks(), totalChunks)); } - // Write chunk to file + // Write chunk to file using streaming to avoid loading entire chunk into memory Path targetPath = fileState.getTargetPath(); long offset = (long) chunkIndex * getChunkSize(); - try (RandomAccessFile raf = new RandomAccessFile(targetPath.toFile(), "rw")) { + try (RandomAccessFile raf = new RandomAccessFile(targetPath.toFile(), "rw"); + var inputStream = chunk.getInputStream()) { raf.seek(offset); - byte[] data = chunk.getBytes(); - raf.write(data); + + // Stream chunk data in smaller buffers to reduce memory pressure + byte[] buffer = new byte[8192]; // 8KB buffer + int bytesRead; + long totalWritten = 0; + + while ((bytesRead = inputStream.read(buffer)) != -1) { + raf.write(buffer, 0, bytesRead); + totalWritten += bytesRead; + } + log.debug("Wrote chunk {} ({} bytes) to {} at offset {}", - chunkIndex, data.length, targetPath.getFileName(), offset); + chunkIndex, totalWritten, targetPath.getFileName(), offset); } fileState.markChunkReceived(chunkIndex); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f9b2f7a..acc8428 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -5,17 +5,19 @@ server.port=8080 spring.application.name=cf-deployer # Multipart Configuration - for traditional single upload endpoint -spring.servlet.multipart.max-file-size=500MB -spring.servlet.multipart.max-request-size=500MB +spring.servlet.multipart.max-file-size=10MB +spring.servlet.multipart.max-request-size=10MB spring.servlet.multipart.enabled=true +# Write all uploads directly to disk, not memory (prevents OutOfMemoryError) +spring.servlet.multipart.file-size-threshold=0 # Cloud Foundry CLI Configuration cf.cli.timeout=600 cf.cli.path= # Chunked Upload Configuration -# Recommended chunk size: 5MB (client-side should match this) -cf.upload.chunk.size=5242880 +# Reduced chunk size to 2MB to avoid memory issues on low-memory Tanzu instances +cf.upload.chunk.size=2097152 # Session timeout in minutes (default: 30 minutes) cf.upload.session.timeout-minutes=30