@forzalabs/remora 1.1.11 → 1.1.12
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/documentation/default_resources/consumer.json +16 -52
- package/documentation/default_resources/mock_data.csv +6 -0
- package/documentation/default_resources/producer.json +15 -32
- package/documentation/default_resources/project.json +2 -2
- package/documentation/default_resources/source.json +7 -14
- package/index.js +46 -26
- package/package.json +1 -1
- package/workers/ExecutorWorker.js +35 -16
|
@@ -1,53 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"fields": [
|
|
21
|
-
{ "key": "<producer field name>", "from": "<producer name>" },
|
|
22
|
-
{ "key": "<original field name>", "from": "<producer name>", "alias": "<new field name>" },
|
|
23
|
-
{ "key": "<secondary producer field name>", "from": "<secondary producer name>" },
|
|
24
|
-
{ "key": "<another field name>", "from": "<producer name>" }
|
|
25
|
-
],
|
|
26
|
-
"filters": [
|
|
27
|
-
{
|
|
28
|
-
"sql": "<filter condition>"
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"outputs": [
|
|
32
|
-
{ "format": "API" },
|
|
33
|
-
{
|
|
34
|
-
"format": "JSON",
|
|
35
|
-
"exportDestination": "<export destination>"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"format": "CSV",
|
|
39
|
-
"exportDestination": "<export destination>",
|
|
40
|
-
"trigger": {
|
|
41
|
-
"type": "CRON",
|
|
42
|
-
"value": "0 0 * * *"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
],
|
|
46
|
-
"metadata": {
|
|
47
|
-
"<metadata tag key>": "<metadata tag value>",
|
|
48
|
-
"owner_email": "<owner email>"
|
|
49
|
-
},
|
|
50
|
-
"project": "<project name>",
|
|
51
|
-
"schema": "<schema name>",
|
|
52
|
-
"_version": 1
|
|
53
|
-
}
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/ForzaLabs/remora-public/refs/heads/main/json_schemas/consumer-schema.json",
|
|
3
|
+
"name": "c_default",
|
|
4
|
+
"producers": [
|
|
5
|
+
{ "name": "p_default" }
|
|
6
|
+
],
|
|
7
|
+
"fields": [
|
|
8
|
+
{ "key": "id" },
|
|
9
|
+
{ "key": "name" },
|
|
10
|
+
{ "key": "age" },
|
|
11
|
+
{ "key": "country" },
|
|
12
|
+
{ "key": "spend" }
|
|
13
|
+
],
|
|
14
|
+
"outputs": [
|
|
15
|
+
{ "format": "JSON", "exportDestination": "s_default" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -1,33 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"mask": "<hash | mask | crypt>",
|
|
18
|
-
"description": "<field description>"
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
"measures": [
|
|
22
|
-
{
|
|
23
|
-
"name": "<calculated measure name>",
|
|
24
|
-
"description": "<measure description>",
|
|
25
|
-
"sql": "<sql expression>"
|
|
26
|
-
}
|
|
27
|
-
],
|
|
28
|
-
"settings": {
|
|
29
|
-
"sqlTable": "<source table name>",
|
|
30
|
-
"direct": true
|
|
31
|
-
},
|
|
32
|
-
"_version": 1
|
|
33
|
-
}
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/ForzaLabs/remora-public/refs/heads/main/json_schemas/producer-schema.json",
|
|
3
|
+
"name": "p_default",
|
|
4
|
+
"source": "s_default",
|
|
5
|
+
"dimensions": [
|
|
6
|
+
{ "name": "id", "type": "string" },
|
|
7
|
+
{ "name": "name", "type": "string" },
|
|
8
|
+
{ "name": "age", "type": "number" },
|
|
9
|
+
{ "name": "country", "type": "string" },
|
|
10
|
+
{ "name": "spend", "type": "number" }
|
|
11
|
+
],
|
|
12
|
+
"settings": {
|
|
13
|
+
"fileType": "CSV",
|
|
14
|
+
"fileKey": "mock_data.csv"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/ForzaLabs/remora-public/refs/heads/main/json_schemas/project-schema.json",
|
|
3
|
-
"name": "
|
|
3
|
+
"name": "Default Remora Project",
|
|
4
4
|
"version": "1.0.0",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "This is the standard Remora project created when you run init.",
|
|
6
6
|
"consumers": ["/consumers"],
|
|
7
7
|
"producers": ["/producers"],
|
|
8
8
|
"sources": ["/sources"],
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"accessKey": "<access key var from env>",
|
|
10
|
-
"secretKey": "<secret key var from env>",
|
|
11
|
-
"region": "<aws region>",
|
|
12
|
-
"database": "<db name>",
|
|
13
|
-
"workgroup": "<db workgroup>"
|
|
14
|
-
},
|
|
15
|
-
"engine": "<aws-redshift | aws-dynamodb | aws-s3 | postgres | local>"
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/ForzaLabs/remora-public/refs/heads/main/json_schemas/source-schema.json",
|
|
3
|
+
"name": "s_default",
|
|
4
|
+
"authentication": {
|
|
5
|
+
"method": "implicit",
|
|
6
|
+
"path": "./default_remora_data"
|
|
7
|
+
},
|
|
8
|
+
"engine": "local"
|
|
16
9
|
}
|
package/index.js
CHANGED
|
@@ -13228,6 +13228,8 @@ var FileLogServiceClass = class {
|
|
|
13228
13228
|
constructor() {
|
|
13229
13229
|
this._enabled = false;
|
|
13230
13230
|
this.enable = (folder = "logs", file = "remora.log") => {
|
|
13231
|
+
this._folder = folder;
|
|
13232
|
+
this._file = file;
|
|
13231
13233
|
this._logger = import_winston.default.createLogger({
|
|
13232
13234
|
level: "debug",
|
|
13233
13235
|
format: import_winston.default.format.combine(
|
|
@@ -13260,6 +13262,23 @@ ${stack}` : base;
|
|
|
13260
13262
|
});
|
|
13261
13263
|
};
|
|
13262
13264
|
this.flush = () => {
|
|
13265
|
+
if (!this._enabled || !this._logger) return Promise.resolve();
|
|
13266
|
+
return new Promise((resolve) => {
|
|
13267
|
+
let pending = this._logger.transports.length;
|
|
13268
|
+
if (pending === 0) return resolve();
|
|
13269
|
+
for (const transport of this._logger.transports) {
|
|
13270
|
+
if (typeof transport.on === "function") {
|
|
13271
|
+
transport.once("logged", () => {
|
|
13272
|
+
if (--pending === 0) resolve();
|
|
13273
|
+
});
|
|
13274
|
+
this._logger.info("");
|
|
13275
|
+
} else {
|
|
13276
|
+
if (--pending === 0) resolve();
|
|
13277
|
+
}
|
|
13278
|
+
}
|
|
13279
|
+
});
|
|
13280
|
+
};
|
|
13281
|
+
this.close = () => {
|
|
13263
13282
|
if (!this._enabled || !this._logger) return Promise.resolve();
|
|
13264
13283
|
return new Promise((resolve) => {
|
|
13265
13284
|
this._logger.on("finish", resolve);
|
|
@@ -13339,6 +13358,7 @@ var Logger = class {
|
|
|
13339
13358
|
FileLogService_default.write("INFO", String(message));
|
|
13340
13359
|
};
|
|
13341
13360
|
this.flush = () => FileLogService_default.flush();
|
|
13361
|
+
this.close = () => FileLogService_default.close();
|
|
13342
13362
|
this.error = (error) => {
|
|
13343
13363
|
let message;
|
|
13344
13364
|
let stack;
|
|
@@ -13480,7 +13500,7 @@ var import_promises = __toESM(require("fs/promises"), 1);
|
|
|
13480
13500
|
|
|
13481
13501
|
// ../../packages/constants/src/Constants.ts
|
|
13482
13502
|
var CONSTANTS = {
|
|
13483
|
-
cliVersion: "1.1.
|
|
13503
|
+
cliVersion: "1.1.12",
|
|
13484
13504
|
backendVersion: 1,
|
|
13485
13505
|
backendPort: 5088,
|
|
13486
13506
|
workerVersion: 2,
|
|
@@ -16071,7 +16091,7 @@ var DOCUMENTATION_DIR = resolveAssetDir("documentation");
|
|
|
16071
16091
|
|
|
16072
16092
|
// src/actions/init.ts
|
|
16073
16093
|
var init = async () => {
|
|
16074
|
-
console.log(import_chalk5.default.blue.bold("\u{1F4E6} Initializing your
|
|
16094
|
+
console.log(import_chalk5.default.blue.bold("\u{1F4E6} Initializing your Remora app (make sure you have set your REMORA_LICENCE_KEY in the environment variables)..."));
|
|
16075
16095
|
try {
|
|
16076
16096
|
const spinner = (0, import_ora3.default)("Creating configuration files...").start();
|
|
16077
16097
|
const directories = [
|
|
@@ -16079,23 +16099,22 @@ var init = async () => {
|
|
|
16079
16099
|
"remora/consumers",
|
|
16080
16100
|
"remora/producers",
|
|
16081
16101
|
"remora/schemas",
|
|
16082
|
-
"remora/sources"
|
|
16102
|
+
"remora/sources",
|
|
16103
|
+
"default_remora_data"
|
|
16083
16104
|
];
|
|
16084
16105
|
const defaultSource = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "default_resources/source.json"), "utf-8");
|
|
16085
16106
|
const defaultConsumer = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "default_resources/consumer.json"), "utf-8");
|
|
16086
16107
|
const defaultProducer = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "default_resources/producer.json"), "utf-8");
|
|
16087
16108
|
const defaultRemoraProject = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "default_resources/project.json"), "utf-8");
|
|
16109
|
+
const defaultMockData = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "default_resources/mock_data.csv"), "utf-8");
|
|
16088
16110
|
const readme = import_fs_extra2.default.readFileSync(import_path13.default.join(DOCUMENTATION_DIR, "README.md"), "utf-8");
|
|
16089
16111
|
const files = [
|
|
16090
|
-
{ path: "remora/sources
|
|
16091
|
-
{ path: "remora/
|
|
16092
|
-
{ path: "remora/
|
|
16093
|
-
{ path: "remora/consumers/default-consumer.json", content: defaultConsumer },
|
|
16094
|
-
{ path: "remora/producers/.gitkeep", content: "" },
|
|
16095
|
-
{ path: "remora/producers/default-producer.json", content: defaultProducer },
|
|
16096
|
-
{ path: "remora/schemas/.gitkeep", content: "" },
|
|
16112
|
+
{ path: "remora/sources/s_default.json", content: defaultSource },
|
|
16113
|
+
{ path: "remora/consumers/c_default.json", content: defaultConsumer },
|
|
16114
|
+
{ path: "remora/producers/p_default.json", content: defaultProducer },
|
|
16097
16115
|
{ path: "remora/project.json", content: defaultRemoraProject },
|
|
16098
|
-
{ path: "remora/README.md", content: readme }
|
|
16116
|
+
{ path: "remora/README.md", content: readme },
|
|
16117
|
+
{ path: "default_remora_data/mock_data.csv", content: defaultMockData }
|
|
16099
16118
|
];
|
|
16100
16119
|
for (let i = 0; i < directories.length; i++) {
|
|
16101
16120
|
const dir = directories[i];
|
|
@@ -19326,19 +19345,17 @@ var ExecutorWriter_default = ExecutorWriter;
|
|
|
19326
19345
|
var import_promises10 = require("stream/promises");
|
|
19327
19346
|
var ExecutorOrchestratorClass = class {
|
|
19328
19347
|
constructor() {
|
|
19329
|
-
this.
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
maxOldGenerationSizeMb: Constants_default.defaults.MIN_RUNTIME_HEAP_MB
|
|
19335
|
-
}
|
|
19348
|
+
this.createPool = () => {
|
|
19349
|
+
const options = {
|
|
19350
|
+
workerThreadOpts: {
|
|
19351
|
+
resourceLimits: {
|
|
19352
|
+
maxOldGenerationSizeMb: Constants_default.defaults.MIN_RUNTIME_HEAP_MB
|
|
19336
19353
|
}
|
|
19337
|
-
}
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19354
|
+
}
|
|
19355
|
+
};
|
|
19356
|
+
const workerPath = this._getWorkerPath();
|
|
19357
|
+
Logger_default.log(`Initializing worker pool from ${workerPath} (heap limit: ${Constants_default.defaults.MIN_RUNTIME_HEAP_MB}MB)`);
|
|
19358
|
+
return import_workerpool.default.pool(import_path19.default.join(workerPath, "ExecutorWorker.js"), options);
|
|
19342
19359
|
};
|
|
19343
19360
|
this.launch = async (request) => {
|
|
19344
19361
|
Affirm_default(request, "Invalid options");
|
|
@@ -19349,9 +19366,9 @@ var ExecutorOrchestratorClass = class {
|
|
|
19349
19366
|
const _progress = new ExecutorProgress_default(logProgress);
|
|
19350
19367
|
const { usageId } = UsageManager_default.startUsage(consumer, details);
|
|
19351
19368
|
const scope = { id: usageId, folder: `${consumer.name}_${usageId}`, workersId: [], limitFileSize: consumer.MaximumFileSize };
|
|
19369
|
+
const pool = this.createPool();
|
|
19352
19370
|
try {
|
|
19353
19371
|
const start = performance.now();
|
|
19354
|
-
this.init();
|
|
19355
19372
|
const executorResults = [];
|
|
19356
19373
|
Logger_default.log(`[${usageId}] Launching consumer "${consumer.name}" (invoked by: ${details.invokedBy}, user: ${details.user?.name ?? "unknown"}, producer(s): ${consumer.producers.length})`);
|
|
19357
19374
|
let counter = performance.now();
|
|
@@ -19397,16 +19414,16 @@ var ExecutorOrchestratorClass = class {
|
|
|
19397
19414
|
_progress.register((currentWorkerIndex + 1).toString(), prod.name, fileIndex, totalFiles);
|
|
19398
19415
|
scope.workersId.push(workerId);
|
|
19399
19416
|
Logger_default.log(`[${usageId}] Spawning worker ${workerId} for producer "${prod.name}" \u2014 chunk ${chunk.start}-${chunk.end} (${Math.round((chunk.end - chunk.start) / 1024)}KB)`);
|
|
19400
|
-
workerThreads.push(
|
|
19417
|
+
workerThreads.push(pool.exec("executor", [workerData], {
|
|
19401
19418
|
on: (payload) => this.onWorkAdvanced(payload, currentWorkerIndex, _progress)
|
|
19402
19419
|
}));
|
|
19403
19420
|
}
|
|
19404
19421
|
Logger_default.log(`[${usageId}] Waiting for ${workerThreads.length} worker(s) to complete`);
|
|
19405
19422
|
executorResults.push(...await Promise.all(workerThreads));
|
|
19406
19423
|
Logger_default.log(`[${usageId}] All ${workerThreads.length} worker(s) finished for producer "${prod.name}" file ${fileIndex + 1}/${totalFiles}`);
|
|
19407
|
-
await this._executorPool.terminate();
|
|
19408
19424
|
}
|
|
19409
19425
|
}
|
|
19426
|
+
await pool.terminate();
|
|
19410
19427
|
_progress.complete();
|
|
19411
19428
|
if (executorResults.some((x) => !Algo_default.hasVal(x)))
|
|
19412
19429
|
throw new Error(`${executorResults.filter((x) => !Algo_default.hasVal(x)).length} worker(s) failed to produce valid results`);
|
|
@@ -19465,6 +19482,7 @@ var ExecutorOrchestratorClass = class {
|
|
|
19465
19482
|
} catch (error) {
|
|
19466
19483
|
Logger_default.log(`[${usageId}] Consumer "${consumer.name}" failed: ${Helper_default.asError(error).message}`);
|
|
19467
19484
|
Logger_default.error(Helper_default.asError(error));
|
|
19485
|
+
await pool.terminate();
|
|
19468
19486
|
await ConsumerOnFinishManager_default.onConsumerError(consumer, usageId);
|
|
19469
19487
|
Logger_default.log(`[${usageId}] Running cleanup after failure`);
|
|
19470
19488
|
await this.performCleanupOperations(scope, tracker);
|
|
@@ -20070,6 +20088,8 @@ var mock = async (producerName, records) => {
|
|
|
20070
20088
|
|
|
20071
20089
|
// src/index.ts
|
|
20072
20090
|
import_dotenv.default.configDotenv();
|
|
20091
|
+
if (!process.env.NODE_ENV)
|
|
20092
|
+
process.env.NODE_ENV = "production";
|
|
20073
20093
|
if (process.env.NODE_ENV !== "development" && process.env.REMORA_DEBUG_MODE === "true") {
|
|
20074
20094
|
Logger_default.enableFileLogging("./remora/logs");
|
|
20075
20095
|
console.log(`Enabled file logger.`);
|
package/package.json
CHANGED
|
@@ -13222,6 +13222,8 @@ var FileLogServiceClass = class {
|
|
|
13222
13222
|
constructor() {
|
|
13223
13223
|
this._enabled = false;
|
|
13224
13224
|
this.enable = (folder = "logs", file = "remora.log") => {
|
|
13225
|
+
this._folder = folder;
|
|
13226
|
+
this._file = file;
|
|
13225
13227
|
this._logger = import_winston.default.createLogger({
|
|
13226
13228
|
level: "debug",
|
|
13227
13229
|
format: import_winston.default.format.combine(
|
|
@@ -13254,6 +13256,23 @@ ${stack}` : base;
|
|
|
13254
13256
|
});
|
|
13255
13257
|
};
|
|
13256
13258
|
this.flush = () => {
|
|
13259
|
+
if (!this._enabled || !this._logger) return Promise.resolve();
|
|
13260
|
+
return new Promise((resolve) => {
|
|
13261
|
+
let pending = this._logger.transports.length;
|
|
13262
|
+
if (pending === 0) return resolve();
|
|
13263
|
+
for (const transport of this._logger.transports) {
|
|
13264
|
+
if (typeof transport.on === "function") {
|
|
13265
|
+
transport.once("logged", () => {
|
|
13266
|
+
if (--pending === 0) resolve();
|
|
13267
|
+
});
|
|
13268
|
+
this._logger.info("");
|
|
13269
|
+
} else {
|
|
13270
|
+
if (--pending === 0) resolve();
|
|
13271
|
+
}
|
|
13272
|
+
}
|
|
13273
|
+
});
|
|
13274
|
+
};
|
|
13275
|
+
this.close = () => {
|
|
13257
13276
|
if (!this._enabled || !this._logger) return Promise.resolve();
|
|
13258
13277
|
return new Promise((resolve) => {
|
|
13259
13278
|
this._logger.on("finish", resolve);
|
|
@@ -13333,6 +13352,7 @@ var Logger = class {
|
|
|
13333
13352
|
FileLogService_default.write("INFO", String(message));
|
|
13334
13353
|
};
|
|
13335
13354
|
this.flush = () => FileLogService_default.flush();
|
|
13355
|
+
this.close = () => FileLogService_default.close();
|
|
13336
13356
|
this.error = (error) => {
|
|
13337
13357
|
let message;
|
|
13338
13358
|
let stack;
|
|
@@ -13474,7 +13494,7 @@ var import_promises = __toESM(require("fs/promises"), 1);
|
|
|
13474
13494
|
|
|
13475
13495
|
// ../../packages/constants/src/Constants.ts
|
|
13476
13496
|
var CONSTANTS = {
|
|
13477
|
-
cliVersion: "1.1.
|
|
13497
|
+
cliVersion: "1.1.12",
|
|
13478
13498
|
backendVersion: 1,
|
|
13479
13499
|
backendPort: 5088,
|
|
13480
13500
|
workerVersion: 2,
|
|
@@ -19084,19 +19104,17 @@ var ExecutorWriter_default = ExecutorWriter;
|
|
|
19084
19104
|
var import_promises10 = require("stream/promises");
|
|
19085
19105
|
var ExecutorOrchestratorClass = class {
|
|
19086
19106
|
constructor() {
|
|
19087
|
-
this.
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
19091
|
-
|
|
19092
|
-
maxOldGenerationSizeMb: Constants_default.defaults.MIN_RUNTIME_HEAP_MB
|
|
19093
|
-
}
|
|
19107
|
+
this.createPool = () => {
|
|
19108
|
+
const options = {
|
|
19109
|
+
workerThreadOpts: {
|
|
19110
|
+
resourceLimits: {
|
|
19111
|
+
maxOldGenerationSizeMb: Constants_default.defaults.MIN_RUNTIME_HEAP_MB
|
|
19094
19112
|
}
|
|
19095
|
-
}
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19113
|
+
}
|
|
19114
|
+
};
|
|
19115
|
+
const workerPath = this._getWorkerPath();
|
|
19116
|
+
Logger_default.log(`Initializing worker pool from ${workerPath} (heap limit: ${Constants_default.defaults.MIN_RUNTIME_HEAP_MB}MB)`);
|
|
19117
|
+
return import_workerpool.default.pool(import_path16.default.join(workerPath, "ExecutorWorker.js"), options);
|
|
19100
19118
|
};
|
|
19101
19119
|
this.launch = async (request) => {
|
|
19102
19120
|
Affirm_default(request, "Invalid options");
|
|
@@ -19107,9 +19125,9 @@ var ExecutorOrchestratorClass = class {
|
|
|
19107
19125
|
const _progress = new ExecutorProgress_default(logProgress);
|
|
19108
19126
|
const { usageId } = UsageManager_default.startUsage(consumer, details);
|
|
19109
19127
|
const scope = { id: usageId, folder: `${consumer.name}_${usageId}`, workersId: [], limitFileSize: consumer.MaximumFileSize };
|
|
19128
|
+
const pool = this.createPool();
|
|
19110
19129
|
try {
|
|
19111
19130
|
const start = performance.now();
|
|
19112
|
-
this.init();
|
|
19113
19131
|
const executorResults = [];
|
|
19114
19132
|
Logger_default.log(`[${usageId}] Launching consumer "${consumer.name}" (invoked by: ${details.invokedBy}, user: ${details.user?.name ?? "unknown"}, producer(s): ${consumer.producers.length})`);
|
|
19115
19133
|
let counter = performance.now();
|
|
@@ -19155,16 +19173,16 @@ var ExecutorOrchestratorClass = class {
|
|
|
19155
19173
|
_progress.register((currentWorkerIndex + 1).toString(), prod.name, fileIndex, totalFiles);
|
|
19156
19174
|
scope.workersId.push(workerId);
|
|
19157
19175
|
Logger_default.log(`[${usageId}] Spawning worker ${workerId} for producer "${prod.name}" \u2014 chunk ${chunk.start}-${chunk.end} (${Math.round((chunk.end - chunk.start) / 1024)}KB)`);
|
|
19158
|
-
workerThreads.push(
|
|
19176
|
+
workerThreads.push(pool.exec("executor", [workerData], {
|
|
19159
19177
|
on: (payload) => this.onWorkAdvanced(payload, currentWorkerIndex, _progress)
|
|
19160
19178
|
}));
|
|
19161
19179
|
}
|
|
19162
19180
|
Logger_default.log(`[${usageId}] Waiting for ${workerThreads.length} worker(s) to complete`);
|
|
19163
19181
|
executorResults.push(...await Promise.all(workerThreads));
|
|
19164
19182
|
Logger_default.log(`[${usageId}] All ${workerThreads.length} worker(s) finished for producer "${prod.name}" file ${fileIndex + 1}/${totalFiles}`);
|
|
19165
|
-
await this._executorPool.terminate();
|
|
19166
19183
|
}
|
|
19167
19184
|
}
|
|
19185
|
+
await pool.terminate();
|
|
19168
19186
|
_progress.complete();
|
|
19169
19187
|
if (executorResults.some((x) => !Algo_default.hasVal(x)))
|
|
19170
19188
|
throw new Error(`${executorResults.filter((x) => !Algo_default.hasVal(x)).length} worker(s) failed to produce valid results`);
|
|
@@ -19223,6 +19241,7 @@ var ExecutorOrchestratorClass = class {
|
|
|
19223
19241
|
} catch (error) {
|
|
19224
19242
|
Logger_default.log(`[${usageId}] Consumer "${consumer.name}" failed: ${Helper_default.asError(error).message}`);
|
|
19225
19243
|
Logger_default.error(Helper_default.asError(error));
|
|
19244
|
+
await pool.terminate();
|
|
19226
19245
|
await ConsumerOnFinishManager_default.onConsumerError(consumer, usageId);
|
|
19227
19246
|
Logger_default.log(`[${usageId}] Running cleanup after failure`);
|
|
19228
19247
|
await this.performCleanupOperations(scope, tracker);
|