Skip to content

Commit 34da16b

Browse files
committed
fix race condition and update some UI
Signed-off-by: wwanarif <wan.abdul.hakim.b.wan.arif@intel.com>
1 parent 5c57b06 commit 34da16b

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

studio-frontend/packages/server/src/controllers/finetuning/index.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -182,50 +182,43 @@ const downloadFineTuningOutput = async (req: Request, res: Response, next: NextF
182182

183183
const fs = require('fs')
184184

185+
// Get file stats for Content-Length header (enables browser progress bar)
186+
const fileStats = fs.statSync(filePath)
187+
const fileSize = fileStats.size
188+
185189
// Set response headers for file download
186190
const fileName = `${jobId}-output.zip`
187191
res.setHeader('Content-Type', 'application/zip')
188192
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`)
193+
res.setHeader('Content-Length', fileSize)
189194

190195
// Stream the file
191196
const fileStream = fs.createReadStream(filePath)
192197

193198
// Log when stream opens
194199
fileStream.on('open', () => {
195-
console.debug(`finetuningController.downloadFineTuningOutput - starting to stream: ${filePath}`)
200+
console.debug(`finetuningController.downloadFineTuningOutput - starting to stream: ${filePath} (${fileSize} bytes)`)
196201
})
197-
198-
// Delete zip file after response fully finishes (browser completes download)
199-
res.on('finish', () => {
200-
setTimeout(() => {
201-
try {
202-
if (fs.existsSync(filePath)) {
203-
fs.unlinkSync(filePath)
204-
console.debug(`finetuningController.downloadFineTuningOutput - deleted zip after download complete: ${filePath}`)
205-
}
206-
} catch (deleteErr: any) {
207-
console.warn(`finetuningController.downloadFineTuningOutput - failed to delete zip: ${deleteErr?.message || deleteErr}`)
208-
}
209-
}, 100)
202+
203+
// Log when the file stream closes (end of stream on server side)
204+
fileStream.on('close', () => {
205+
console.debug(`finetuningController.downloadFineTuningOutput - end stream: ${filePath}`)
210206
})
211207

208+
// Multiple users can download the same ZIP simultaneously
212209
fileStream.on('error', (err: any) => {
213210
console.error('finetuningController.downloadFineTuningOutput - error streaming file:', err)
214-
// Try to delete zip on error too
215-
try {
216-
if (fs.existsSync(filePath)) {
217-
fs.unlinkSync(filePath)
218-
console.debug(`finetuningController.downloadFineTuningOutput - deleted zip after error: ${filePath}`)
219-
}
220-
} catch (deleteErr: any) {
221-
console.warn(`finetuningController.downloadFineTuningOutput - failed to delete zip on error: ${deleteErr?.message || deleteErr}`)
222-
}
223211
if (!res.headersSent) {
224212
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
225213
error: 'Error streaming fine-tuning output file'
226214
})
227215
}
228216
})
217+
218+
// Log when HTTP response finishes sending bytes to client
219+
res.on('finish', () => {
220+
console.debug(`finetuningController.downloadFineTuningOutput - response finished streaming: ${filePath}`)
221+
})
229222

230223
fileStream.pipe(res)
231224
} catch (error) {

studio-frontend/packages/ui/src/views/finetuning/FinetuningJobModal.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
779779
value={formData.dataset.padding_side}
780780
onChange={(e) => handleConfigChange('dataset', 'padding_side', e.target.value)}
781781
size="small"
782-
sx={{ width: '100%', maxWidth: 240 }}
782+
sx={{ width: '100%' }}
783783
/>
784784
</Box>
785785

@@ -789,7 +789,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
789789
value={formData.dataset.truncation_side}
790790
onChange={(e) => handleConfigChange('dataset', 'truncation_side', e.target.value)}
791791
size="small"
792-
sx={{ width: '100%', maxWidth: 240 }}
792+
sx={{ width: '100%' }}
793793
/>
794794
</Box>
795795

@@ -799,7 +799,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
799799
value={String(formData.dataset.padding)}
800800
onChange={(e) => handleConfigChange('dataset', 'padding', e.target.value)}
801801
size="small"
802-
sx={{ width: '100%', maxWidth: 240 }}
802+
sx={{ width: '100%' }}
803803
/>
804804
</Box>
805805

@@ -809,7 +809,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
809809
value={String(formData.dataset.truncation)}
810810
onChange={(e) => handleConfigChange('dataset', 'truncation', e.target.value)}
811811
size="small"
812-
sx={{ width: '100%', maxWidth: 240 }}
812+
sx={{ width: '100%' }}
813813
/>
814814
</Box>
815815

@@ -819,7 +819,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
819819
value={String(formData.dataset.mask_input)}
820820
onChange={(e) => handleConfigChange('dataset', 'mask_input', e.target.value)}
821821
size="small"
822-
sx={{ width: '100%', maxWidth: 240 }}
822+
sx={{ width: '100%' }}
823823
/>
824824
</Box>
825825

@@ -829,7 +829,7 @@ const FinetuningJobModal = ({ open, onClose, onJobCreated }) => {
829829
value={String(formData.dataset.mask_response)}
830830
onChange={(e) => handleConfigChange('dataset', 'mask_response', e.target.value)}
831831
size="small"
832-
sx={{ width: '100%', maxWidth: 240 }}
832+
sx={{ width: '100%' }}
833833
/>
834834
</Box>
835835
</Box>

0 commit comments

Comments
 (0)