diff options
author | Sam Wilkins <samwilkins333@gmail.com> | 2019-09-13 20:17:19 -0400 |
---|---|---|
committer | Sam Wilkins <samwilkins333@gmail.com> | 2019-09-13 20:17:19 -0400 |
commit | dcbbfe6d34e89df49069a0ede64df0dc5adc6056 (patch) | |
tree | 40749b628d99c7ce7c9e23b00514d5c487e2444f /src/client | |
parent | 3c2b04f16ccfae103e2f3acdd852e337c5f974e1 (diff) |
fixed batching and refactor
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/northstar/utils/Extensions.ts | 13 | ||||
-rw-r--r-- | src/client/util/Import & Export/DirectoryImportBox.tsx | 33 | ||||
-rw-r--r-- | src/client/util/UtilExtensions.ts | 62 |
3 files changed, 52 insertions, 56 deletions
diff --git a/src/client/northstar/utils/Extensions.ts b/src/client/northstar/utils/Extensions.ts index 720f4a062..c866d1bc3 100644 --- a/src/client/northstar/utils/Extensions.ts +++ b/src/client/northstar/utils/Extensions.ts @@ -20,22 +20,17 @@ String.prototype.Truncate = function (length: number, replacement: string): Stri return target; }; -interface Action<T> { - handler: (batch: T[]) => any; - interval?: number; -} -interface BatchParameters<T> { - size: number; - action?: Action<T>; -} +type BatchHandler<I, O> = (batch: I[]) => O[] | Promise<O[]>; interface Array<T> { - batch(parameters: BatchParameters<T>): Promise<T[][]>; + batch(batchSize: number): T[][]; + batchAction<O>(batchSize: number, handler: BatchHandler<T, O>, interval?: number): Promise<O[]>; lastElement(): T; } Array.prototype.batch = extensions.Batch; +Array.prototype.batchAction = extensions.BatchAction; Array.prototype.lastElement = function <T>() { if (!this.length) { diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 5915f3412..1ae0e7525 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -95,25 +95,19 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> let sizes: number[] = []; let modifiedDates: number[] = []; - const uploads: FileResponse[] = []; + const localUpload = async (batch: File[]) => { + sizes.push(...batch.map(file => file.size)); + modifiedDates.push(...batch.map(file => file.lastModified)); - await validated.batch({ - size: 15, - action: { - handler: async (batch: File[]) => { - sizes.push(...batch.map(file => file.size)); - modifiedDates.push(...batch.map(file => file.lastModified)); + let formData = new FormData(); + batch.forEach(file => formData.append(Utils.GenerateGuid(), file)); + const parameters = { method: 'POST', body: formData }; - let formData = new FormData(); - batch.forEach(file => formData.append(Utils.GenerateGuid(), file)); - const parameters = { method: 'POST', body: formData }; - - uploads.push(...(await (await fetch(Utils.prepend(RouteStore.upload), parameters)).json())); + runInAction(() => this.completed += batch.length); + return (await fetch(Utils.prepend(RouteStore.upload), parameters)).json(); + }; - runInAction(() => this.completed += batch.length); - } - } - }); + const uploads = await validated.batchAction<FileResponse>(15, localUpload); await Promise.all(uploads.map(async upload => { const type = upload.type; @@ -149,7 +143,12 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> }; let parent = this.props.ContainingCollectionView; if (parent) { - let importContainer = Docs.Create.MasonryDocument(docs, options); + let importContainer: Doc; + if (docs.length < 50) { + importContainer = Docs.Create.MasonryDocument(docs, options); + } else { + importContainer = Docs.Create.SchemaDocument([], docs, options); + } await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); importContainer.singleColumn = false; Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer); diff --git a/src/client/util/UtilExtensions.ts b/src/client/util/UtilExtensions.ts index 1e277b242..0bf9f4e97 100644 --- a/src/client/util/UtilExtensions.ts +++ b/src/client/util/UtilExtensions.ts @@ -1,39 +1,41 @@ -module.exports.Batch = async function <T>(parameters: BatchParameters<T>) { - const { size, action } = parameters; +module.exports.Batch = function <T>(batchSize: number): T[][] { const batches: T[][] = []; let i = 0; while (i < this.length) { - const cap = Math.min(i + size, this.length); + const cap = Math.min(i + batchSize, this.length); batches.push(this.slice(i, cap)); i = cap; } - console.log(`Beginning action on ${this.length} elements, split into ${batches.length} groups => ${batches.map(batch => batch.length).join(", ")}`); - if (action) { - const { handler, interval } = action; - if (!interval || batches.length === 1) { - for (let batch of batches) { - await handler(batch); - } - } else { - return new Promise<T[][]>(resolve => { - const iterator = batches[Symbol.iterator](); - const quota = batches.length; - let completed = 0; - const tag = setInterval(async () => { - const next = iterator.next(); - if (next.done) { - clearInterval(tag); - return; - } - const batch = next.value; - console.log(`Handling next batch with ${batch.length} elements`); - await handler(batch); - if (++completed === quota) { - resolve(batches); - } - }, interval); - }); + return batches; +}; + +module.exports.BatchAction = async function <I, O>(batchSize: number, handler: BatchHandler<I, O>, interval?: number): Promise<O[]> { + if (!this.length) { + return []; + } + let collector: O[] = []; + const batches = this.batch(batchSize); + if (!interval || batches.length === 1) { + for (let batch of batches) { + collector.push(...(await handler(batch))); } + } else { + return new Promise<O[]>(resolve => { + const iterator = batches[Symbol.iterator](); + let completed = 0; + const tag = setInterval(async () => { + const next = iterator.next(); + if (next.done) { + clearInterval(tag); + return; + } + const batch = next.value; + collector.push(...(await handler(batch))); + if (++completed === batches.length) { + resolve(collector); + } + }, interval); + }); } - return batches; + return collector; };
\ No newline at end of file |