@milaboratories/pl-drivers 1.5.50 → 1.5.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/drivers/upload.d.ts.map +1 -1
- package/dist/drivers/upload_task.d.ts +11 -1
- package/dist/drivers/upload_task.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/drivers/download_blob.ts +1 -1
- package/src/drivers/upload.ts +3 -2
- package/src/drivers/upload_task.ts +74 -39
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-drivers",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.51",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20"
|
|
6
6
|
},
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"tar-fs": "^3.0.8",
|
|
31
31
|
"undici": "~7.5.0",
|
|
32
32
|
"zod": "~3.23.8",
|
|
33
|
+
"@milaboratories/pl-client": "^2.9.0",
|
|
33
34
|
"@milaboratories/computable": "^2.4.7",
|
|
35
|
+
"@milaboratories/pl-model-common": "^1.14.0",
|
|
34
36
|
"@milaboratories/ts-helpers": "^1.2.0",
|
|
35
|
-
"@milaboratories/pl-tree": "^1.6.0"
|
|
36
|
-
"@milaboratories/pl-client": "^2.9.0",
|
|
37
|
-
"@milaboratories/pl-model-common": "^1.14.0"
|
|
37
|
+
"@milaboratories/pl-tree": "^1.6.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"eslint": "^9.
|
|
40
|
+
"eslint": "^9.25.1",
|
|
41
41
|
"@types/decompress": "^4.2.7",
|
|
42
42
|
"typescript": "~5.5.4",
|
|
43
43
|
"vite": "^5.4.11",
|
|
@@ -252,7 +252,7 @@ export class DownloadDriver implements BlobDriver {
|
|
|
252
252
|
public getComputableContent(
|
|
253
253
|
res: ResourceInfo | PlTreeEntry
|
|
254
254
|
): ComputableStableDefined<Uint8Array>{
|
|
255
|
-
return Computable.make((ctx) =>
|
|
255
|
+
return Computable.make((ctx) =>
|
|
256
256
|
this.getDownloadedBlob(res, ctx), {
|
|
257
257
|
postprocessValue: (v) => v ? this.getContent(v.handle) : undefined
|
|
258
258
|
}
|
package/src/drivers/upload.ts
CHANGED
|
@@ -26,7 +26,7 @@ import { scheduler } from 'node:timers/promises';
|
|
|
26
26
|
import type { PollingOps } from './helpers/polling_ops';
|
|
27
27
|
import type { ImportResourceSnapshot } from './types';
|
|
28
28
|
import { IndexResourceSnapshot, UploadResourceSnapshot } from './types';
|
|
29
|
-
import { nonRecoverableError, UploadTask } from './upload_task';
|
|
29
|
+
import { isMyUpload, nonRecoverableError, UploadTask } from './upload_task';
|
|
30
30
|
import { WrongResourceTypeError } from './helpers/helpers';
|
|
31
31
|
|
|
32
32
|
export function makeBlobImportSnapshot(
|
|
@@ -145,11 +145,12 @@ export class UploadDriver {
|
|
|
145
145
|
|
|
146
146
|
this.idToProgress.set(res.id, newTask);
|
|
147
147
|
|
|
148
|
-
if (newTask.shouldScheduleUpload())
|
|
148
|
+
if (newTask.shouldScheduleUpload()) {
|
|
149
149
|
this.uploadQueue.push({
|
|
150
150
|
fn: () => newTask.uploadBlobTask(),
|
|
151
151
|
recoverableErrorPredicate: (e) => !nonRecoverableError(e),
|
|
152
152
|
});
|
|
153
|
+
}
|
|
153
154
|
|
|
154
155
|
newTask.setDoneIfOutputSet(res);
|
|
155
156
|
return newTask.getProgress(w, callerId);
|
|
@@ -10,6 +10,7 @@ import { MTimeError, NoFileForUploading, UnexpectedEOF } from '../clients/upload
|
|
|
10
10
|
import type { ImportResourceSnapshot } from './types';
|
|
11
11
|
import { ImportFileHandleUploadData } from './types';
|
|
12
12
|
import assert from 'node:assert';
|
|
13
|
+
import { ResourceInfo } from '@milaboratories/pl-tree';
|
|
13
14
|
|
|
14
15
|
/** Holds all info needed to upload a file and a status of uploading
|
|
15
16
|
* and indexing. Also, has a method to update a status of the progress.
|
|
@@ -58,49 +59,25 @@ export class UploadTask {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
public shouldScheduleUpload(): boolean {
|
|
61
|
-
return this.progress
|
|
62
|
+
return isMyUpload(this.progress);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
/** Uploads a blob if it's not BlobIndex. */
|
|
65
66
|
public async uploadBlobTask() {
|
|
66
|
-
assert(isUpload(this.res), 'the upload operation can be done only for BlobUploads');
|
|
67
|
-
const timeout = 10000; // 10 sec instead of standard 5 sec, things might be slow with a slow connection.
|
|
68
|
-
|
|
69
67
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
await uploadBlob(
|
|
69
|
+
this.logger,
|
|
70
|
+
this.clientBlob,
|
|
71
|
+
this.res,
|
|
72
|
+
this.uploadData!,
|
|
73
|
+
this.isComputableDone.bind(this),
|
|
74
|
+
{
|
|
75
|
+
nPartsWithThisUploadSpeed: this.nPartsWithThisUploadSpeed,
|
|
76
|
+
nPartsToIncreaseUpload: this.nPartsToIncreaseUpload,
|
|
77
|
+
currentSpeed: this.nMaxUploads,
|
|
78
|
+
maxSpeed: this.maxNConcurrentPartsUpload,
|
|
79
|
+
},
|
|
76
80
|
);
|
|
77
|
-
|
|
78
|
-
const partUploadFn = (part: bigint) => async (controller: AsyncPoolController) => {
|
|
79
|
-
if (this.isComputableDone()) return;
|
|
80
|
-
await this.clientBlob.partUpload(
|
|
81
|
-
this.res,
|
|
82
|
-
this.uploadData!.localPath,
|
|
83
|
-
BigInt(this.uploadData!.modificationTime),
|
|
84
|
-
part,
|
|
85
|
-
{ timeout }
|
|
86
|
-
);
|
|
87
|
-
this.logger.info(`uploaded chunk ${part}/${parts.overall} of resource: ${this.res.id}`);
|
|
88
|
-
|
|
89
|
-
// if we had a network freeze, it will be increased slowly.
|
|
90
|
-
this.nPartsWithThisUploadSpeed++;
|
|
91
|
-
if (this.nPartsWithThisUploadSpeed >= this.nPartsToIncreaseUpload) {
|
|
92
|
-
this.nPartsWithThisUploadSpeed = 0;
|
|
93
|
-
this.nMaxUploads = increaseConcurrency(this.logger, this.nMaxUploads, this.maxNConcurrentPartsUpload);
|
|
94
|
-
controller.setConcurrency(this.nMaxUploads);
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
await asyncPool(this.nMaxUploads, parts.toUpload.map(partUploadFn));
|
|
99
|
-
|
|
100
|
-
if (this.isComputableDone()) return;
|
|
101
|
-
await this.clientBlob.finalize(this.res, { timeout });
|
|
102
|
-
|
|
103
|
-
this.logger.info(`uploading of resource ${this.res.id} finished.`);
|
|
104
81
|
this.change.markChanged();
|
|
105
82
|
} catch (e: any) {
|
|
106
83
|
this.setRetriableError(e);
|
|
@@ -207,6 +184,59 @@ export class UploadTask {
|
|
|
207
184
|
}
|
|
208
185
|
}
|
|
209
186
|
|
|
187
|
+
/** Uploads a blob if it's not BlobIndex. */
|
|
188
|
+
export async function uploadBlob(
|
|
189
|
+
logger: MiLogger,
|
|
190
|
+
clientBlob: ClientUpload,
|
|
191
|
+
res: ResourceInfo,
|
|
192
|
+
uploadData: ImportFileHandleUploadData,
|
|
193
|
+
isDoneFn: () => boolean,
|
|
194
|
+
speed: {
|
|
195
|
+
nPartsWithThisUploadSpeed: number,
|
|
196
|
+
nPartsToIncreaseUpload: number,
|
|
197
|
+
currentSpeed: number,
|
|
198
|
+
maxSpeed: number,
|
|
199
|
+
},
|
|
200
|
+
) {
|
|
201
|
+
assert(isUpload(res), 'the upload operation can be done only for BlobUploads');
|
|
202
|
+
const timeout = 10000; // 10 sec instead of standard 5 sec, things might be slow with a slow connection.
|
|
203
|
+
|
|
204
|
+
if (isDoneFn()) return;
|
|
205
|
+
const parts = await clientBlob.initUpload(res, { timeout });
|
|
206
|
+
logger.info(
|
|
207
|
+
`started to upload blob ${res.id},`
|
|
208
|
+
+ ` parts overall: ${parts.overall}, parts remained: ${parts.toUpload.length},`
|
|
209
|
+
+ ` number of concurrent uploads: ${speed.currentSpeed}`,
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const partUploadFn = (part: bigint) => async (controller: AsyncPoolController) => {
|
|
213
|
+
if (isDoneFn()) return;
|
|
214
|
+
await clientBlob.partUpload(
|
|
215
|
+
res,
|
|
216
|
+
uploadData.localPath,
|
|
217
|
+
BigInt(uploadData.modificationTime),
|
|
218
|
+
part,
|
|
219
|
+
{ timeout }
|
|
220
|
+
);
|
|
221
|
+
logger.info(`uploaded chunk ${part}/${parts.overall} of resource: ${res.id}`);
|
|
222
|
+
|
|
223
|
+
// if we had a network freeze, it will be increased slowly.
|
|
224
|
+
speed.nPartsWithThisUploadSpeed++;
|
|
225
|
+
if (speed.nPartsWithThisUploadSpeed >= speed.nPartsToIncreaseUpload) {
|
|
226
|
+
speed.nPartsWithThisUploadSpeed = 0;
|
|
227
|
+
speed.currentSpeed = increaseConcurrency(logger, speed.currentSpeed, speed.maxSpeed);
|
|
228
|
+
controller.setConcurrency(speed.currentSpeed);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
await asyncPool(speed.currentSpeed, parts.toUpload.map(partUploadFn));
|
|
233
|
+
|
|
234
|
+
if (isDoneFn()) return;
|
|
235
|
+
await clientBlob.finalize(res, { timeout });
|
|
236
|
+
|
|
237
|
+
logger.info(`uploading of resource ${res.id} finished.`);
|
|
238
|
+
}
|
|
239
|
+
|
|
210
240
|
function newProgress(res: ImportResourceSnapshot, signer: Signer) {
|
|
211
241
|
let isUploadSignMatch: boolean | undefined;
|
|
212
242
|
let uploadData: ImportFileHandleUploadData | undefined;
|
|
@@ -223,10 +253,15 @@ function newProgress(res: ImportResourceSnapshot, signer: Signer) {
|
|
|
223
253
|
isUpload: isUpload(res),
|
|
224
254
|
isUploadSignMatch: isUploadSignMatch,
|
|
225
255
|
lastError: undefined,
|
|
226
|
-
},
|
|
256
|
+
} satisfies sdk.ImportProgress,
|
|
227
257
|
};
|
|
228
258
|
}
|
|
229
259
|
|
|
260
|
+
/** Returns true if we need to upload the blob that got from this progress. */
|
|
261
|
+
export function isMyUpload(p: sdk.ImportProgress): boolean {
|
|
262
|
+
return p.isUpload && (p.isUploadSignMatch ?? false);
|
|
263
|
+
}
|
|
264
|
+
|
|
230
265
|
/** Creates a deep copy of progress,
|
|
231
266
|
* since we do not want to pass a mutable object
|
|
232
267
|
* to API, it led to bugs before.
|
|
@@ -256,7 +291,7 @@ function isImportResourceOutputSet(res: ImportResourceSnapshot) {
|
|
|
256
291
|
: res.fields.incarnation !== undefined;
|
|
257
292
|
}
|
|
258
293
|
|
|
259
|
-
function isUpload(res:
|
|
294
|
+
function isUpload(res: ResourceInfo) {
|
|
260
295
|
return res.type.name.startsWith('BlobUpload');
|
|
261
296
|
}
|
|
262
297
|
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './drivers/download_blob';
|
|
|
9
9
|
export * from './drivers/download_blob_url/driver';
|
|
10
10
|
export * from './drivers/download_blob_url/snapshot';
|
|
11
11
|
export * from './drivers/upload';
|
|
12
|
+
export * from './drivers/upload_task';
|
|
12
13
|
export * from './drivers/logs_stream';
|
|
13
14
|
export * from './drivers/logs';
|
|
14
15
|
export * from './drivers/download_url';
|