Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 60824c9

Browse files
committedFeb 27, 2024
fix(react-native): dispose blob slice chunks after consume
1 parent 4540c45 commit 60824c9

File tree

5 files changed

+53
-32
lines changed

5 files changed

+53
-32
lines changed
 

‎packages/upload-client/src/uploadFile/prepareChunks.browser.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const prepareChunks: PrepareChunks = async (
77
fileSize: number,
88
chunkSize: number
99
) => {
10-
return (index: number): BrowserFile =>
11-
sliceChunk(file as BrowserFile, index, fileSize, chunkSize)
10+
return {
11+
getChunk: (index: number): BrowserFile =>
12+
sliceChunk(file as BrowserFile, index, fileSize, chunkSize)
13+
}
1214
}

‎packages/upload-client/src/uploadFile/prepareChunks.node.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const prepareChunks: PrepareChunks = async (
77
fileSize: number,
88
chunkSize: number
99
) => {
10-
return (index: number): NodeFile =>
11-
sliceChunk(file as NodeFile, index, fileSize, chunkSize)
10+
return {
11+
getChunk: (index: number): NodeFile =>
12+
sliceChunk(file as NodeFile, index, fileSize, chunkSize)
13+
}
1214
}

‎packages/upload-client/src/uploadFile/prepareChunks.react-native.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isReactNativeAsset } from '../tools/isFileData'
2-
import { SupportedFileInput } from '../types'
2+
import { Sliceable, SupportedFileInput } from '../types'
33
import { getBlobFromReactNativeAsset } from '../tools/getBlobFromReactNativeAsset'
44
import { sliceChunk } from './sliceChunk'
55
import { PrepareChunks } from './types'
@@ -19,17 +19,26 @@ export const prepareChunks: PrepareChunks = async (
1919
fileSize: number,
2020
chunkSize: number
2121
) => {
22-
let blob: Blob
22+
let blob: Sliceable
2323
if (isReactNativeAsset(file)) {
2424
blob = await getBlobFromReactNativeAsset(file)
2525
} else {
26-
blob = file as Blob
26+
blob = file as Sliceable
2727
}
2828

29-
const chunks: Blob[] = []
30-
return (index: number): Blob => {
31-
const chunk = sliceChunk(blob, index, fileSize, chunkSize)
32-
chunks.push(chunk)
33-
return chunk
29+
const chunks: Set<Sliceable> = new Set()
30+
return {
31+
getChunk: (index: number): Sliceable => {
32+
const chunk = sliceChunk(blob, index, fileSize, chunkSize)
33+
chunks.add(chunk)
34+
return chunk
35+
},
36+
/**
37+
* Remove references to all the chunks from the memory to make able
38+
* react-native to deallocate it
39+
*/
40+
disposeChunks: () => {
41+
chunks.clear()
42+
}
3443
}
3544
}

‎packages/upload-client/src/uploadFile/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ export type PrepareChunks = (
2828
file: SupportedFileInput,
2929
fileSize: number,
3030
chunkSize: number
31-
) => Promise<(index: number) => Sliceable>
31+
) => Promise<{
32+
getChunk: (index: number) => Sliceable
33+
disposeChunks?: () => void
34+
}>

‎packages/upload-client/src/uploadFile/uploadMultipart.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -146,27 +146,32 @@ export const uploadMultipart = async (
146146
metadata
147147
})
148148
.then(async ({ uuid, parts }) => {
149-
const getChunk = await prepareChunks(file, size, multipartChunkSize)
150-
return Promise.all([
151-
uuid,
152-
runWithConcurrency(
153-
maxConcurrentRequests,
154-
parts.map(
155-
(url, index) => (): Promise<MultipartUploadResponse> =>
156-
uploadPart(getChunk(index), url, {
157-
publicKey,
158-
contentType,
159-
onProgress: createProgressHandler(parts.length, index),
160-
signal,
161-
integration,
162-
retryThrottledRequestMaxTimes,
163-
retryNetworkErrorMaxTimes
164-
})
165-
)
149+
const { getChunk, disposeChunks } = await prepareChunks(
150+
file,
151+
size,
152+
multipartChunkSize
153+
)
154+
await runWithConcurrency(
155+
maxConcurrentRequests,
156+
parts.map(
157+
(url, index) => async (): Promise<MultipartUploadResponse> => {
158+
const chunk = getChunk(index)
159+
return uploadPart(chunk, url, {
160+
publicKey,
161+
contentType,
162+
onProgress: createProgressHandler(parts.length, index),
163+
signal,
164+
integration,
165+
retryThrottledRequestMaxTimes,
166+
retryNetworkErrorMaxTimes
167+
})
168+
}
166169
)
167-
])
170+
).finally(() => disposeChunks?.())
171+
172+
return uuid
168173
})
169-
.then(([uuid]) =>
174+
.then((uuid) =>
170175
multipartComplete(uuid, {
171176
publicKey,
172177
baseURL,

0 commit comments

Comments
 (0)
Please sign in to comment.