Skip to content

Commit

Permalink
fix(react-native): dispose blob slice chunks after consume
Browse files Browse the repository at this point in the history
  • Loading branch information
nd0ut committed Feb 27, 2024
1 parent 4540c45 commit 677726d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const prepareChunks: PrepareChunks = async (
fileSize: number,
chunkSize: number
) => {
return (index: number): BrowserFile =>
sliceChunk(file as BrowserFile, index, fileSize, chunkSize)
return {
getChunk: (index: number): BrowserFile =>
sliceChunk(file as BrowserFile, index, fileSize, chunkSize)
}
}
6 changes: 4 additions & 2 deletions packages/upload-client/src/uploadFile/prepareChunks.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const prepareChunks: PrepareChunks = async (
fileSize: number,
chunkSize: number
) => {
return (index: number): NodeFile =>
sliceChunk(file as NodeFile, index, fileSize, chunkSize)
return {
getChunk: (index: number): NodeFile =>
sliceChunk(file as NodeFile, index, fileSize, chunkSize)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isReactNativeAsset } from '../tools/isFileData'
import { SupportedFileInput } from '../types'
import { Sliceable, SupportedFileInput } from '../types'
import { getBlobFromReactNativeAsset } from '../tools/getBlobFromReactNativeAsset'
import { sliceChunk } from './sliceChunk'
import { PrepareChunks } from './types'
Expand All @@ -19,17 +19,33 @@ export const prepareChunks: PrepareChunks = async (
fileSize: number,
chunkSize: number
) => {
let blob: Blob
let blob: Sliceable
if (isReactNativeAsset(file)) {
blob = await getBlobFromReactNativeAsset(file)
} else {
blob = file as Blob
blob = file as Sliceable
}

const chunks: Blob[] = []
return (index: number): Blob => {
const chunk = sliceChunk(blob, index, fileSize, chunkSize)
chunks.push(chunk)
return chunk
const chunks: Set<Sliceable> = new Set()
return {
getChunk: (index: number): Sliceable => {
const chunk = sliceChunk(blob, index, fileSize, chunkSize)
chunks.add(chunk)
return chunk
},
/**
* Remove references to all the chunks from the memory to make able
* react-native to deallocate it
*/
disposeChunks: () => {
chunks.clear()
},
/**
* Remove specific chunk reference from the memory to make able react-native
* to deallocate it
*/
disposeChunk: (chunk: Sliceable) => {
chunks.delete(chunk)
}
}
}
6 changes: 5 additions & 1 deletion packages/upload-client/src/uploadFile/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ export type PrepareChunks = (
file: SupportedFileInput,
fileSize: number,
chunkSize: number
) => Promise<(index: number) => Sliceable>
) => Promise<{
getChunk: (index: number) => Sliceable
disposeChunk?: (chunk: Sliceable) => void
disposeChunks?: () => void
}>
43 changes: 24 additions & 19 deletions packages/upload-client/src/uploadFile/uploadMultipart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,27 +146,32 @@ export const uploadMultipart = async (
metadata
})
.then(async ({ uuid, parts }) => {
const getChunk = await prepareChunks(file, size, multipartChunkSize)
return Promise.all([
uuid,
runWithConcurrency(
maxConcurrentRequests,
parts.map(
(url, index) => (): Promise<MultipartUploadResponse> =>
uploadPart(getChunk(index), url, {
publicKey,
contentType,
onProgress: createProgressHandler(parts.length, index),
signal,
integration,
retryThrottledRequestMaxTimes,
retryNetworkErrorMaxTimes
})
)
const { getChunk, disposeChunks, disposeChunk } = await prepareChunks(
file,
size,
multipartChunkSize
)
await runWithConcurrency(
maxConcurrentRequests,
parts.map(
(url, index) => async (): Promise<MultipartUploadResponse> => {
const chunk = getChunk(index)
return uploadPart(chunk, url, {
publicKey,
contentType,
onProgress: createProgressHandler(parts.length, index),
signal,
integration,
retryThrottledRequestMaxTimes,
retryNetworkErrorMaxTimes
}).finally(() => disposeChunk?.(chunk))
}
)
])
).finally(() => disposeChunks?.())

return uuid
})
.then(([uuid]) =>
.then((uuid) =>
multipartComplete(uuid, {
publicKey,
baseURL,
Expand Down

0 comments on commit 677726d

Please sign in to comment.