@certik/skynet 0.25.4 → 0.25.6
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/CHANGELOG.md +10 -1
- package/bun.lockb +0 -0
- package/dist/api.js +10 -1
- package/dist/app.js +21 -2
- package/dist/deploy.js +10 -1
- package/dist/dynamodb.d.ts +2 -1
- package/dist/dynamodb.js +6 -0
- package/dist/indexer.js +21 -2
- package/dist/selector.js +10 -1
- package/package.json +1 -1
- package/src/dynamodb.ts +7 -0
- package/src/indexer.ts +9 -2
- package/src/selector.ts +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.6
|
|
4
|
+
|
|
5
|
+
- Fix Nomad job names for indexers with boolean selector flags: `getJobName` no longer appends `-false` when optional flags default to `false` (e.g. `force`, `forceUpdate`). Unset string selectors (`undefined`, `null`, empty string) are also omitted from the job name suffix.
|
|
6
|
+
|
|
7
|
+
## 0.25.5
|
|
8
|
+
|
|
9
|
+
- Fix indexer process hanging after execution completes due to open DynamoDB HTTP keep-alive connections
|
|
10
|
+
- Add missing `process.exit(0)` on successful completion of `reset`, `validate`, `delta` (no-op), and stateless `build` modes
|
|
11
|
+
- Add `destroyDynamoDB` helper to properly close the DynamoDB client and release sockets
|
|
12
|
+
|
|
3
13
|
## 0.25.4
|
|
4
14
|
|
|
5
15
|
- Added `email` module with `sendEmail` helper for sending emails via Mailgun
|
|
@@ -77,7 +87,6 @@
|
|
|
77
87
|
## 0.20.0
|
|
78
88
|
|
|
79
89
|
- Fix databricks with bun (extra step needed for projects using the lib):
|
|
80
|
-
|
|
81
90
|
- Copy the patch file `patches/@databricks%2Fsql@1.9.0.patch`
|
|
82
91
|
- Add the following configs to your `package.json`:
|
|
83
92
|
|
package/bun.lockb
ADDED
|
Binary file
|
package/dist/api.js
CHANGED
|
@@ -101,8 +101,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
101
101
|
function normalizeSelectorValue(v) {
|
|
102
102
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
103
103
|
}
|
|
104
|
+
function includeSelectorValueInJobName(value) {
|
|
105
|
+
if (value === false)
|
|
106
|
+
return false;
|
|
107
|
+
if (value === undefined || value === null)
|
|
108
|
+
return false;
|
|
109
|
+
if (value === "")
|
|
110
|
+
return false;
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
104
113
|
function getJobName(name, selectorFlags, mode) {
|
|
105
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
114
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
106
115
|
let jobName = name;
|
|
107
116
|
if (mode) {
|
|
108
117
|
jobName += `-${mode}`;
|
package/dist/app.js
CHANGED
|
@@ -564,6 +564,11 @@ async function deleteRecordsByHashKey(tableName, indexName, hashKeyValue, verbos
|
|
|
564
564
|
}
|
|
565
565
|
return totalDeleted;
|
|
566
566
|
}
|
|
567
|
+
function destroyDynamoDB() {
|
|
568
|
+
if (_dynamoDB) {
|
|
569
|
+
_dynamoDB.destroy();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
567
572
|
// src/selector.ts
|
|
568
573
|
function getSelectorDesc(selector) {
|
|
569
574
|
return Object.keys(selector).map((name) => {
|
|
@@ -591,8 +596,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
591
596
|
function normalizeSelectorValue(v) {
|
|
592
597
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
593
598
|
}
|
|
599
|
+
function includeSelectorValueInJobName(value) {
|
|
600
|
+
if (value === false)
|
|
601
|
+
return false;
|
|
602
|
+
if (value === undefined || value === null)
|
|
603
|
+
return false;
|
|
604
|
+
if (value === "")
|
|
605
|
+
return false;
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
594
608
|
function getJobName(name, selectorFlags, mode) {
|
|
595
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
609
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
596
610
|
let jobName = name;
|
|
597
611
|
if (mode) {
|
|
598
612
|
jobName += `-${mode}`;
|
|
@@ -743,6 +757,7 @@ function createModeIndexerApp({
|
|
|
743
757
|
inline.log(`[MODE INDEXER] mode=${mode}, env=${getEnvironment()}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
744
758
|
if (mode === "reset") {
|
|
745
759
|
await runReset(selectorFlags);
|
|
760
|
+
process.exit(0);
|
|
746
761
|
} else if (mode === "rebuild") {
|
|
747
762
|
const rebuildFrom = from || await finalState.getMinId(selectorFlags);
|
|
748
763
|
const rebuildTo = to || await finalState.getMaxId(selectorFlags);
|
|
@@ -854,6 +869,7 @@ function createModeIndexerApp({
|
|
|
854
869
|
}
|
|
855
870
|
}
|
|
856
871
|
inline.log(`[MODE INDEXER] validated ${offsetRange(from, to)} ${finalState.type} successfully in ${Date.now() - startTime}ms`);
|
|
872
|
+
process.exit(0);
|
|
857
873
|
}
|
|
858
874
|
async function execBuild(selectorFlags, from, to, verbose, shouldSaveState = false) {
|
|
859
875
|
let failedIds = [];
|
|
@@ -929,7 +945,7 @@ function createModeIndexerApp({
|
|
|
929
945
|
const startTime = Date.now();
|
|
930
946
|
if (to < from) {
|
|
931
947
|
inline.log(`[MODE INDEXER] skip delta, there're no more items need to be processed, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
932
|
-
|
|
948
|
+
process.exit(0);
|
|
933
949
|
}
|
|
934
950
|
inline.log(`[MODE INDEXER] starting delta, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}, batchSize=${buildBatchSize}, concurrency=${buildConcurrency}`);
|
|
935
951
|
try {
|
|
@@ -1028,6 +1044,8 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1028
1044
|
} catch (err) {
|
|
1029
1045
|
inline.error(err);
|
|
1030
1046
|
process.exit(1);
|
|
1047
|
+
} finally {
|
|
1048
|
+
destroyDynamoDB();
|
|
1031
1049
|
}
|
|
1032
1050
|
}
|
|
1033
1051
|
return { run };
|
|
@@ -1087,6 +1105,7 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1087
1105
|
throw new Error(`[INDEXER] Build failed due to critical errors`);
|
|
1088
1106
|
}
|
|
1089
1107
|
inline.log(`[INDEXER] build successfully in ${Date.now() - startTime}ms`);
|
|
1108
|
+
process.exit(0);
|
|
1090
1109
|
}
|
|
1091
1110
|
return runBuild(cli.flags).catch((err) => {
|
|
1092
1111
|
inline.error(err);
|
package/dist/deploy.js
CHANGED
|
@@ -44,8 +44,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
44
44
|
function normalizeSelectorValue(v) {
|
|
45
45
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
46
46
|
}
|
|
47
|
+
function includeSelectorValueInJobName(value) {
|
|
48
|
+
if (value === false)
|
|
49
|
+
return false;
|
|
50
|
+
if (value === undefined || value === null)
|
|
51
|
+
return false;
|
|
52
|
+
if (value === "")
|
|
53
|
+
return false;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
47
56
|
function getJobName(name, selectorFlags, mode) {
|
|
48
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
57
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
49
58
|
let jobName = name;
|
|
50
59
|
if (mode) {
|
|
51
60
|
jobName += `-${mode}`;
|
package/dist/dynamodb.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ declare function getRecordByKey<T>(tableName: string, keys: Record<string, unkno
|
|
|
13
13
|
declare function updateRecordByKey(tableName: string, idKey: Record<string, unknown>, fields: Record<string, unknown>, conditionExpressions?: null, verbose?: boolean): Promise<Record<string, any> | undefined>;
|
|
14
14
|
declare function batchDeleteRecords(tableName: string, keys: Record<string, unknown>[]): Promise<void>;
|
|
15
15
|
declare function deleteRecordsByHashKey(tableName: string, indexName: string | undefined, hashKeyValue: string, verbose?: boolean): Promise<number>;
|
|
16
|
-
|
|
16
|
+
declare function destroyDynamoDB(): void;
|
|
17
|
+
export { getDocClient, destroyDynamoDB, ScanCommand, BatchWriteCommand, GetCommand, PutCommand, QueryCommand, UpdateCommand, scanWholeTable, batchCreateRecords, createRecord, getRecordsByKey, getRecordByKey, updateRecordByKey, batchDeleteRecords, deleteRecordsByHashKey, };
|
package/dist/dynamodb.js
CHANGED
|
@@ -460,12 +460,18 @@ async function deleteRecordsByHashKey(tableName, indexName, hashKeyValue, verbos
|
|
|
460
460
|
}
|
|
461
461
|
return totalDeleted;
|
|
462
462
|
}
|
|
463
|
+
function destroyDynamoDB() {
|
|
464
|
+
if (_dynamoDB) {
|
|
465
|
+
_dynamoDB.destroy();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
463
468
|
export {
|
|
464
469
|
updateRecordByKey,
|
|
465
470
|
scanWholeTable,
|
|
466
471
|
getRecordsByKey,
|
|
467
472
|
getRecordByKey,
|
|
468
473
|
getDocClient,
|
|
474
|
+
destroyDynamoDB,
|
|
469
475
|
deleteRecordsByHashKey,
|
|
470
476
|
createRecord,
|
|
471
477
|
batchDeleteRecords,
|
package/dist/indexer.js
CHANGED
|
@@ -564,6 +564,11 @@ async function deleteRecordsByHashKey(tableName, indexName, hashKeyValue, verbos
|
|
|
564
564
|
}
|
|
565
565
|
return totalDeleted;
|
|
566
566
|
}
|
|
567
|
+
function destroyDynamoDB() {
|
|
568
|
+
if (_dynamoDB) {
|
|
569
|
+
_dynamoDB.destroy();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
567
572
|
// src/selector.ts
|
|
568
573
|
function getSelectorDesc(selector) {
|
|
569
574
|
return Object.keys(selector).map((name) => {
|
|
@@ -591,8 +596,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
591
596
|
function normalizeSelectorValue(v) {
|
|
592
597
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
593
598
|
}
|
|
599
|
+
function includeSelectorValueInJobName(value) {
|
|
600
|
+
if (value === false)
|
|
601
|
+
return false;
|
|
602
|
+
if (value === undefined || value === null)
|
|
603
|
+
return false;
|
|
604
|
+
if (value === "")
|
|
605
|
+
return false;
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
594
608
|
function getJobName(name, selectorFlags, mode) {
|
|
595
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
609
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
596
610
|
let jobName = name;
|
|
597
611
|
if (mode) {
|
|
598
612
|
jobName += `-${mode}`;
|
|
@@ -743,6 +757,7 @@ function createModeIndexerApp({
|
|
|
743
757
|
inline.log(`[MODE INDEXER] mode=${mode}, env=${getEnvironment()}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
744
758
|
if (mode === "reset") {
|
|
745
759
|
await runReset(selectorFlags);
|
|
760
|
+
process.exit(0);
|
|
746
761
|
} else if (mode === "rebuild") {
|
|
747
762
|
const rebuildFrom = from || await finalState.getMinId(selectorFlags);
|
|
748
763
|
const rebuildTo = to || await finalState.getMaxId(selectorFlags);
|
|
@@ -854,6 +869,7 @@ function createModeIndexerApp({
|
|
|
854
869
|
}
|
|
855
870
|
}
|
|
856
871
|
inline.log(`[MODE INDEXER] validated ${offsetRange(from, to)} ${finalState.type} successfully in ${Date.now() - startTime}ms`);
|
|
872
|
+
process.exit(0);
|
|
857
873
|
}
|
|
858
874
|
async function execBuild(selectorFlags, from, to, verbose, shouldSaveState = false) {
|
|
859
875
|
let failedIds = [];
|
|
@@ -929,7 +945,7 @@ function createModeIndexerApp({
|
|
|
929
945
|
const startTime = Date.now();
|
|
930
946
|
if (to < from) {
|
|
931
947
|
inline.log(`[MODE INDEXER] skip delta, there're no more items need to be processed, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
932
|
-
|
|
948
|
+
process.exit(0);
|
|
933
949
|
}
|
|
934
950
|
inline.log(`[MODE INDEXER] starting delta, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}, batchSize=${buildBatchSize}, concurrency=${buildConcurrency}`);
|
|
935
951
|
try {
|
|
@@ -1028,6 +1044,8 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1028
1044
|
} catch (err) {
|
|
1029
1045
|
inline.error(err);
|
|
1030
1046
|
process.exit(1);
|
|
1047
|
+
} finally {
|
|
1048
|
+
destroyDynamoDB();
|
|
1031
1049
|
}
|
|
1032
1050
|
}
|
|
1033
1051
|
return { run };
|
|
@@ -1087,6 +1105,7 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1087
1105
|
throw new Error(`[INDEXER] Build failed due to critical errors`);
|
|
1088
1106
|
}
|
|
1089
1107
|
inline.log(`[INDEXER] build successfully in ${Date.now() - startTime}ms`);
|
|
1108
|
+
process.exit(0);
|
|
1090
1109
|
}
|
|
1091
1110
|
return runBuild(cli.flags).catch((err) => {
|
|
1092
1111
|
inline.error(err);
|
package/dist/selector.js
CHANGED
|
@@ -25,8 +25,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
25
25
|
function normalizeSelectorValue(v) {
|
|
26
26
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
27
27
|
}
|
|
28
|
+
function includeSelectorValueInJobName(value) {
|
|
29
|
+
if (value === false)
|
|
30
|
+
return false;
|
|
31
|
+
if (value === undefined || value === null)
|
|
32
|
+
return false;
|
|
33
|
+
if (value === "")
|
|
34
|
+
return false;
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
28
37
|
function getJobName(name, selectorFlags, mode) {
|
|
29
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
38
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
30
39
|
let jobName = name;
|
|
31
40
|
if (mode) {
|
|
32
41
|
jobName += `-${mode}`;
|
package/package.json
CHANGED
package/src/dynamodb.ts
CHANGED
|
@@ -475,8 +475,15 @@ async function deleteRecordsByHashKey(
|
|
|
475
475
|
return totalDeleted;
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
function destroyDynamoDB() {
|
|
479
|
+
if (_dynamoDB) {
|
|
480
|
+
_dynamoDB.destroy();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
478
484
|
export {
|
|
479
485
|
getDocClient,
|
|
486
|
+
destroyDynamoDB,
|
|
480
487
|
// export common dynamodb commands to make it easier to use
|
|
481
488
|
ScanCommand,
|
|
482
489
|
BatchWriteCommand,
|
package/src/indexer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import meow from "meow";
|
|
2
|
-
import { createRecord, getRecordByKey } from "./dynamodb";
|
|
2
|
+
import { createRecord, getRecordByKey, destroyDynamoDB } from "./dynamodb";
|
|
3
3
|
import { getEnvironment } from "./env";
|
|
4
4
|
import { exponentialRetry } from "./availability";
|
|
5
5
|
import { range as numberRange, fillRange as fillNumberRange } from "./util";
|
|
@@ -213,6 +213,7 @@ function createModeIndexerApp<T extends IndexerStateValue, TSelector extends Sel
|
|
|
213
213
|
|
|
214
214
|
if (mode === "reset") {
|
|
215
215
|
await runReset(selectorFlags);
|
|
216
|
+
process.exit(0);
|
|
216
217
|
} else if (mode === "rebuild") {
|
|
217
218
|
const rebuildFrom = from || (await finalState.getMinId(selectorFlags));
|
|
218
219
|
const rebuildTo = to || (await finalState.getMaxId(selectorFlags));
|
|
@@ -389,6 +390,8 @@ function createModeIndexerApp<T extends IndexerStateValue, TSelector extends Sel
|
|
|
389
390
|
inline.log(
|
|
390
391
|
`[MODE INDEXER] validated ${offsetRange(from, to)} ${finalState.type} successfully in ${Date.now() - startTime}ms`,
|
|
391
392
|
);
|
|
393
|
+
|
|
394
|
+
process.exit(0);
|
|
392
395
|
}
|
|
393
396
|
|
|
394
397
|
async function execBuild(
|
|
@@ -521,7 +524,7 @@ function createModeIndexerApp<T extends IndexerStateValue, TSelector extends Sel
|
|
|
521
524
|
)}`,
|
|
522
525
|
);
|
|
523
526
|
|
|
524
|
-
|
|
527
|
+
process.exit(0);
|
|
525
528
|
}
|
|
526
529
|
|
|
527
530
|
inline.log(
|
|
@@ -646,6 +649,8 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
646
649
|
} catch (err) {
|
|
647
650
|
inline.error(err);
|
|
648
651
|
process.exit(1);
|
|
652
|
+
} finally {
|
|
653
|
+
destroyDynamoDB();
|
|
649
654
|
}
|
|
650
655
|
}
|
|
651
656
|
|
|
@@ -731,6 +736,8 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
731
736
|
}
|
|
732
737
|
|
|
733
738
|
inline.log(`[INDEXER] build successfully in ${Date.now() - startTime}ms`);
|
|
739
|
+
|
|
740
|
+
process.exit(0);
|
|
734
741
|
}
|
|
735
742
|
|
|
736
743
|
return runBuild(cli.flags as ModeIndexerFlags<TSelector>).catch((err) => {
|
package/src/selector.ts
CHANGED
|
@@ -49,10 +49,20 @@ function normalizeSelectorValue(v: string) {
|
|
|
49
49
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/** Values that should not affect Nomad job names (unset / default-off selectors). */
|
|
53
|
+
function includeSelectorValueInJobName(value: unknown): boolean {
|
|
54
|
+
if (value === false) return false;
|
|
55
|
+
if (value === undefined || value === null) return false;
|
|
56
|
+
if (value === "") return false;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
function getJobName<TSelector extends Selector>(name: string, selectorFlags: SelectorFlags<TSelector>, mode?: string) {
|
|
53
61
|
const selectorNamePart = Object.keys(selectorFlags)
|
|
54
62
|
.sort()
|
|
55
|
-
.map((
|
|
63
|
+
.map((key) => selectorFlags[key])
|
|
64
|
+
.filter(includeSelectorValueInJobName)
|
|
65
|
+
.map((value) => String(value))
|
|
56
66
|
.join("-");
|
|
57
67
|
|
|
58
68
|
let jobName = name;
|