@speedkit/cli 2.35.0 → 2.37.0
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 +14 -0
- package/README.md +3 -2
- package/dist/commands/generate-pop-config.d.ts +1 -0
- package/dist/commands/generate-pop-config.js +19 -9
- package/dist/services/cli/cli-service-model.d.ts +1 -0
- package/dist/services/cli/cli-service.d.ts +1 -1
- package/dist/services/prewarm/pre-warm-service.d.ts +2 -0
- package/dist/services/prewarm/pre-warm-service.js +16 -0
- package/oclif.manifest.json +8 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [2.37.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.36.0...v2.37.0) (2024-07-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **prewarm:** show minimal output on quietMode ([aa847d8](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/aa847d8c5ccaacbbcf94c1128973fb5af23f9e33))
|
|
7
|
+
|
|
8
|
+
# [2.36.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.35.0...v2.36.0) (2024-06-27)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **pop-prewarming:** update shielding configuration ([7aa22b6](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/7aa22b6f7a754fc8cb5fdc01454c4c4167e65035))
|
|
14
|
+
|
|
1
15
|
# [2.35.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.34.0...v2.35.0) (2024-06-21)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ $ npm install -g @speedkit/cli
|
|
|
21
21
|
$ sk COMMAND
|
|
22
22
|
running command...
|
|
23
23
|
$ sk (--version)
|
|
24
|
-
@speedkit/cli/2.
|
|
24
|
+
@speedkit/cli/2.37.0 linux-x64 node-v20.15.0
|
|
25
25
|
$ sk --help [COMMAND]
|
|
26
26
|
USAGE
|
|
27
27
|
$ sk COMMAND
|
|
@@ -287,7 +287,7 @@ Generate a pop config for the given app
|
|
|
287
287
|
|
|
288
288
|
```
|
|
289
289
|
USAGE
|
|
290
|
-
$ sk generate-pop-config APP [-c <value>] [-d] [-p <value>] [-t <value>] [-r]
|
|
290
|
+
$ sk generate-pop-config APP [-c <value>] [-d] [-p <value>] [-t <value>] [-r] [-s]
|
|
291
291
|
|
|
292
292
|
ARGUMENTS
|
|
293
293
|
APP The customers appName
|
|
@@ -298,6 +298,7 @@ FLAGS
|
|
|
298
298
|
deployment will be skipped or forced.
|
|
299
299
|
-p, --pop-limit=<value> [default: 5] The maximal pop count which should prewarmed.
|
|
300
300
|
-r, --use-rum Compute the pop statistics based on RUM. Otherwise the real Speed Kit traffic is used.
|
|
301
|
+
-s, --force-shield Force a shield based prewarming config.
|
|
301
302
|
-t, --traffic-share=<value> [default: 5] The minimum traffic share in percent a pop must have to be actually
|
|
302
303
|
prewarmed.
|
|
303
304
|
|
|
@@ -11,6 +11,7 @@ export default class GeneratePopConfig extends Command {
|
|
|
11
11
|
"pop-limit": import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
12
|
"traffic-share": import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
13
|
"use-rum": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
"force-shield": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
15
|
};
|
|
15
16
|
createPopPrewarmingCode(popConfig: string): Promise<string>;
|
|
16
17
|
deployPrewarmingConfig(app: string, config: string, deploy: boolean | undefined): Promise<void>;
|
|
@@ -40,6 +40,11 @@ const SHIELDS = [
|
|
|
40
40
|
pop: "HKG",
|
|
41
41
|
shield: "Hongkong Shield",
|
|
42
42
|
},
|
|
43
|
+
{
|
|
44
|
+
condition: ({ pop }) => ["NRT", "ITM", "TYO", "HND"].includes(pop),
|
|
45
|
+
pop: "NRT",
|
|
46
|
+
shield: "Tokyo Shield",
|
|
47
|
+
},
|
|
43
48
|
{
|
|
44
49
|
condition: ({ region }) => region === "Asia-South",
|
|
45
50
|
pop: "DEL",
|
|
@@ -109,6 +114,11 @@ class GeneratePopConfig extends core_1.Command {
|
|
|
109
114
|
default: false,
|
|
110
115
|
description: "Compute the pop statistics based on RUM. Otherwise the real Speed Kit traffic is used.",
|
|
111
116
|
}),
|
|
117
|
+
"force-shield": core_1.Flags.boolean({
|
|
118
|
+
char: "s",
|
|
119
|
+
default: false,
|
|
120
|
+
description: "Force a shield based prewarming config.",
|
|
121
|
+
}),
|
|
112
122
|
};
|
|
113
123
|
async createPopPrewarmingCode(popConfig) {
|
|
114
124
|
const revalidationTemplate = await (0, file_helper_1.readLocalFile)(__dirname, "../templates/speedKit.Revalidated.js");
|
|
@@ -136,13 +146,13 @@ class GeneratePopConfig extends core_1.Command {
|
|
|
136
146
|
}
|
|
137
147
|
}
|
|
138
148
|
async run() {
|
|
139
|
-
const { args: { app }, flags: { coverage, deploy, "pop-limit": popLimit, "traffic-share": minimalShare, "use-rum": useRum, }, } = await this.parse(GeneratePopConfig);
|
|
149
|
+
const { args: { app }, flags: { coverage, deploy, "pop-limit": popLimit, "traffic-share": minimalShare, "use-rum": useRum, "force-shield": forceShield, }, } = await this.parse(GeneratePopConfig);
|
|
140
150
|
// @todo refactor businessCode from this command to src/pop-config/pop-config-service
|
|
141
151
|
const popConfigService = await new pop_config_1.PopConfigFactory().getService();
|
|
142
152
|
const result = await popConfigService.getUsedPopsPerOrigin(app, useRum);
|
|
143
153
|
const originStats = this.generateOriginStats(result).filter((stats) => stats.hits > 1000);
|
|
144
|
-
this.printStats(originStats, coverage / 100, minimalShare / 100, popLimit);
|
|
145
|
-
const popConfig = this.generatePopConfig(originStats, coverage / 100, minimalShare / 100, popLimit);
|
|
154
|
+
this.printStats(originStats, coverage / 100, minimalShare / 100, popLimit, forceShield);
|
|
155
|
+
const popConfig = this.generatePopConfig(originStats, coverage / 100, minimalShare / 100, popLimit, forceShield);
|
|
146
156
|
await this.deployPrewarmingConfig(app, popConfig, deploy);
|
|
147
157
|
}
|
|
148
158
|
byHitsDesc(a, b) {
|
|
@@ -202,10 +212,10 @@ class GeneratePopConfig extends core_1.Command {
|
|
|
202
212
|
}))
|
|
203
213
|
.sort(this.byHitsDesc);
|
|
204
214
|
}
|
|
205
|
-
generatePopConfig(originStats, coverage, minimalShare, popLimit) {
|
|
215
|
+
generatePopConfig(originStats, coverage, minimalShare, popLimit, forceShield) {
|
|
206
216
|
const originConfigs = { DEFAULT: [] };
|
|
207
217
|
for (const originStat of originStats) {
|
|
208
|
-
originConfigs[originStat.origin] = this.generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit).pops.map((pop) => "POP." + pop);
|
|
218
|
+
originConfigs[originStat.origin] = this.generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit, forceShield).pops.map((pop) => "POP." + pop);
|
|
209
219
|
}
|
|
210
220
|
const serializedConfig = JSON.stringify(originConfigs, null, " ")
|
|
211
221
|
.replaceAll(/"(POP.*?)"/g, "$1")
|
|
@@ -262,10 +272,10 @@ const ORIGIN_POPS = ${serializedConfig}`;
|
|
|
262
272
|
}
|
|
263
273
|
return { edgeCoverage, pops, requiresShielding: true, shieldCoverage };
|
|
264
274
|
}
|
|
265
|
-
generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit) {
|
|
275
|
+
generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit, forceShield) {
|
|
266
276
|
// Use shields if we need to prewar more than 5 pops to achieve the coverage
|
|
267
277
|
const useShieldPrewarming = originStat.pops[popLimit - 1]?.coverage < coverage;
|
|
268
|
-
if (useShieldPrewarming) {
|
|
278
|
+
if (useShieldPrewarming || forceShield) {
|
|
269
279
|
return this.generatePopListByShields(originStat, coverage, minimalShare, popLimit);
|
|
270
280
|
}
|
|
271
281
|
return this.generatePopListByPops(originStat, coverage, minimalShare);
|
|
@@ -279,7 +289,7 @@ const ORIGIN_POPS = ${serializedConfig}`;
|
|
|
279
289
|
}
|
|
280
290
|
return { pop: s.pop, shield: s.shield };
|
|
281
291
|
}
|
|
282
|
-
printStats(originStats, coverage, minimalShare, popLimit) {
|
|
292
|
+
printStats(originStats, coverage, minimalShare, popLimit, forceShield) {
|
|
283
293
|
let shieldingRequired = false;
|
|
284
294
|
for (const originStat of originStats) {
|
|
285
295
|
this.log(`${originStat.origin} ${originStat.hits}`);
|
|
@@ -303,7 +313,7 @@ const ORIGIN_POPS = ${serializedConfig}`;
|
|
|
303
313
|
if (popStats.coverage >= coverage || popStats.share < minimalShare)
|
|
304
314
|
break;
|
|
305
315
|
}
|
|
306
|
-
const config = this.generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit);
|
|
316
|
+
const config = this.generatePrewarmingConfig(originStat, coverage, minimalShare, popLimit, forceShield);
|
|
307
317
|
this.log(" --------------------");
|
|
308
318
|
if (config.requiresShielding)
|
|
309
319
|
this.log(" Final shield coverage: " +
|
|
@@ -12,6 +12,7 @@ export declare enum CliActionStatus {
|
|
|
12
12
|
}
|
|
13
13
|
export interface CliServiceInterface {
|
|
14
14
|
style: chalk.Chalk;
|
|
15
|
+
readonly quiet: boolean;
|
|
15
16
|
code(code: string, buffered?: boolean): void;
|
|
16
17
|
codeStyle(code: string): string;
|
|
17
18
|
comment(message: string, buffered?: boolean): void;
|
|
@@ -3,7 +3,7 @@ import { table } from "@oclif/core/lib/cli-ux/styled/table";
|
|
|
3
3
|
import { Options } from "cli-progress";
|
|
4
4
|
import { CliActionStatus, CliServiceInterface } from "./cli-service-model";
|
|
5
5
|
export declare class CliService implements CliServiceInterface {
|
|
6
|
-
|
|
6
|
+
readonly quiet: boolean;
|
|
7
7
|
style: chalk.Chalk;
|
|
8
8
|
private buffer;
|
|
9
9
|
private progressBar?;
|
|
@@ -6,6 +6,7 @@ export declare class PreWarmService {
|
|
|
6
6
|
private cli;
|
|
7
7
|
private urls;
|
|
8
8
|
private variations;
|
|
9
|
+
private requestsSend;
|
|
9
10
|
constructor(assetClient: AssetApiClient, cli: CliServiceInterface, urls: string[], variations: string[]);
|
|
10
11
|
handleRequestCallback(assetClient: AssetApiClient, entry: AssetItemInterface): Promise<void>;
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -18,4 +19,5 @@ export declare class PreWarmService {
|
|
|
18
19
|
private stopProgressBar;
|
|
19
20
|
private updateProgressBar;
|
|
20
21
|
private updateRateLimit;
|
|
22
|
+
private showMinimalStatusUpdate;
|
|
21
23
|
}
|
|
@@ -10,6 +10,7 @@ class PreWarmService {
|
|
|
10
10
|
cli;
|
|
11
11
|
urls;
|
|
12
12
|
variations;
|
|
13
|
+
requestsSend = 0;
|
|
13
14
|
constructor(assetClient, cli, urls, variations) {
|
|
14
15
|
this.assetClient = assetClient;
|
|
15
16
|
this.cli = cli;
|
|
@@ -56,6 +57,8 @@ class PreWarmService {
|
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
this.cli.write("Retry rateLimited requests.");
|
|
60
|
+
// reset for minimal output
|
|
61
|
+
this.requestsSend = 0;
|
|
59
62
|
const urlsToRetry = assetList
|
|
60
63
|
.getByStatus(_1.ItemStatus.RETRY)
|
|
61
64
|
.map((entry) => entry.url);
|
|
@@ -80,6 +83,7 @@ class PreWarmService {
|
|
|
80
83
|
offset += batch.length;
|
|
81
84
|
this.updateProgressBar(offset, assetList);
|
|
82
85
|
await this.updateRateLimit(batch);
|
|
86
|
+
this.showMinimalStatusUpdate(batch, assetList);
|
|
83
87
|
// fetch next batch
|
|
84
88
|
await this.fetchBatch(assetList, offset);
|
|
85
89
|
}
|
|
@@ -150,5 +154,17 @@ class PreWarmService {
|
|
|
150
154
|
this.assetClient.reduceMaxRequestsPerSecond();
|
|
151
155
|
}
|
|
152
156
|
}
|
|
157
|
+
showMinimalStatusUpdate(batch, assetList) {
|
|
158
|
+
if (!this.cli.quiet) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.requestsSend += batch.length;
|
|
162
|
+
const assetLength = assetList.getLength();
|
|
163
|
+
const errors = assetList.getErrorCount();
|
|
164
|
+
const success = assetList.getSuccessCount();
|
|
165
|
+
const retry = assetList.getRetryCount();
|
|
166
|
+
const currentRate = this.assetClient.getRateLimit();
|
|
167
|
+
this.cli.write(this.cli.style.gray(`${this.requestsSend}/${assetLength} | rate: ${currentRate} | success: ${success} | retry: ${retry} | errors: ${errors}`));
|
|
168
|
+
}
|
|
153
169
|
}
|
|
154
170
|
exports.PreWarmService = PreWarmService;
|
package/oclif.manifest.json
CHANGED
|
@@ -378,6 +378,13 @@
|
|
|
378
378
|
"name": "use-rum",
|
|
379
379
|
"allowNo": false,
|
|
380
380
|
"type": "boolean"
|
|
381
|
+
},
|
|
382
|
+
"force-shield": {
|
|
383
|
+
"char": "s",
|
|
384
|
+
"description": "Force a shield based prewarming config.",
|
|
385
|
+
"name": "force-shield",
|
|
386
|
+
"allowNo": false,
|
|
387
|
+
"type": "boolean"
|
|
381
388
|
}
|
|
382
389
|
},
|
|
383
390
|
"hasDynamicHelp": false,
|
|
@@ -681,5 +688,5 @@
|
|
|
681
688
|
]
|
|
682
689
|
}
|
|
683
690
|
},
|
|
684
|
-
"version": "2.
|
|
691
|
+
"version": "2.37.0"
|
|
685
692
|
}
|