req-rain 0.1.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/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # RequestRain
2
+
3
+ A testing tool that sends many requests to an HTTP server.
4
+
5
+ ```
6
+ Usage: reqrain [options] <server-url>
7
+
8
+ Sends multiple requests to an HTTP server.
9
+
10
+ Arguments:
11
+ server-url HTTP server URL.
12
+
13
+ Options:
14
+ -V, --version output the version number
15
+ --threads <quant> Number of threads to be used.
16
+ Default: 2
17
+ --req-delay <ms> Delay in milliseconds for each request per thread.
18
+ Default: 20
19
+ -h, --help display help for command
20
+ ```
21
+
22
+ ## Example:
23
+ ```
24
+ reqrain http://localhost:8080 --threads 3
25
+ ```
package/bin/reqrain ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/env node
2
+ import "../dist/cli.js";
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare let options: {
2
+ serverURL: string;
3
+ threads: number;
4
+ reqDelay: number;
5
+ };
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAKA,eAAO,IAAI,OAAO;;;;CAIjB,CAAA"}
package/dist/cli.js ADDED
@@ -0,0 +1,42 @@
1
+ import path from "path";
2
+ import { Command } from "commander";
3
+ const program = new Command();
4
+ export let options = {
5
+ serverURL: "",
6
+ threads: 2,
7
+ reqDelay: 20
8
+ };
9
+ const programName = process.argv[1] ? path.basename(process.argv[1]) : "reqrain";
10
+ program
11
+ .name(programName)
12
+ .version("0.1.0")
13
+ .description("Envia múltiplas requisições a um servidor HTTP.");
14
+ program
15
+ .argument("<server-url>", "URL do servidor HTTP.")
16
+ .option("--threads <quant>", "Quantidade de threads a serem usados. Padrão: " + options.threads)
17
+ .option("--req-delay <ms>", "Delay em milisegundos para cada requisição. Padrão: " + options.reqDelay)
18
+ .action(function (serverURL) {
19
+ try {
20
+ new URL(serverURL);
21
+ }
22
+ catch {
23
+ this.error("URL inválida: " + serverURL);
24
+ }
25
+ options.serverURL = serverURL;
26
+ const opts = this.opts();
27
+ if (opts.threads) {
28
+ const threads = Number(opts.threads);
29
+ if (Number.isNaN(threads) || threads < 1)
30
+ this.error("Quantidade de threads inválida: " + opts.threads);
31
+ options.threads = threads;
32
+ }
33
+ if (opts.reqDelay) {
34
+ const delay = Number(opts.reqDelay);
35
+ if (Number.isNaN(delay) || delay < 1)
36
+ this.error("Delay inválido: " + opts.reqDelay);
37
+ options.reqDelay = delay;
38
+ }
39
+ });
40
+ program.parse();
41
+ import("./main.js");
42
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,MAAM,CAAC,IAAI,OAAO,GAAG;IACjB,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,EAAE;CACf,CAAA;AAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAEjF,OAAO;KACF,IAAI,CAAC,WAAW,CAAC;KACjB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,iDAAiD,CAAC,CAAA;AAEnE,OAAO;KACF,QAAQ,CAAC,cAAc,EAAE,uBAAuB,CAAC;KACjD,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,GAAG,OAAO,CAAC,OAAO,CAAC;KAC/F,MAAM,CAAC,kBAAkB,EAAE,sDAAsD,GAAG,OAAO,CAAC,QAAQ,CAAC;KACrG,MAAM,CAAC,UAAS,SAAS;IACtB,IAAI,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IACtB,CAAC;IACD,MAAM,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAE9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAEzB,IAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,IAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,kCAAkC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IAC9B,CAAC;IAED,IAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEpF,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC;IAC7B,CAAC;AACL,CAAC,CAAC,CAAA;AAEN,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,MAAM,CAAC,WAAW,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAA"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/dist/main.js ADDED
@@ -0,0 +1,30 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { options } from "./cli.js";
4
+ import { Piscina } from "piscina";
5
+ const { serverURL, threads, reqDelay } = options;
6
+ const pool = new Piscina({
7
+ filename: path.resolve(fileURLToPath(import.meta.url), "../worker.js"),
8
+ minThreads: threads, maxThreads: threads
9
+ });
10
+ const messageChannel = new MessageChannel();
11
+ let requests = 0;
12
+ let errorCount = 0;
13
+ let lastRequests = requests;
14
+ pool.on("message", (data) => {
15
+ let quant = data.quantity;
16
+ if (data.errors) {
17
+ errorCount += data.errors;
18
+ }
19
+ requests += quant;
20
+ });
21
+ setInterval(() => {
22
+ if (requests === lastRequests)
23
+ return;
24
+ process.stdout.write(`\x1b[0G\x1b[2K${requests} requesições. ${errorCount} erros.`);
25
+ lastRequests = requests;
26
+ }, 50);
27
+ for (let i = 0; i < threads; i++) {
28
+ pool.run({ serverURL, reqDelay });
29
+ }
30
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;AAEjD,MAAM,IAAI,GAAG,IAAI,OAAO,CAA8B;IAClD,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC;IACtE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO;CAC3C,CAAC,CAAA;AAEF,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;AAE5C,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,IAAI,YAAY,GAAG,QAAQ,CAAC;AAE5B,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;IACxB,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;IAE1B,IAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,QAAQ,IAAI,KAAK,CAAC;AACtB,CAAC,CAAC,CAAA;AAEF,WAAW,CAAC,GAAG,EAAE;IACb,IAAG,QAAQ,KAAK,YAAY;QAAE,OAAO;IAErC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,QAAQ,iBAAiB,UAAU,SAAS,CAAC,CAAC;IACpF,YAAY,GAAG,QAAQ,CAAC;AAC5B,CAAC,EAAE,EAAE,CAAC,CAAA;AAEN,KAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CACJ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAC1B,CAAC;AACN,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface PingOptions {
2
+ serverURL: string;
3
+ reqDelay: number;
4
+ }
5
+ export interface PingResultData {
6
+ quantity: number;
7
+ errors?: number;
8
+ }
9
+ export default function startPings({ serverURL, reqDelay }: PingOptions): Promise<unknown>;
10
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,WAAW,oBAwBtE"}
package/dist/worker.js ADDED
@@ -0,0 +1,23 @@
1
+ import fs from "fs";
2
+ import { parentPort } from "worker_threads";
3
+ export default function startPings({ serverURL, reqDelay }) {
4
+ let requests = 0;
5
+ let errors = 0;
6
+ setInterval(() => {
7
+ fetch(serverURL)
8
+ .catch((e) => {
9
+ errors++;
10
+ });
11
+ requests++;
12
+ if (requests % 19 === 0) {
13
+ parentPort?.postMessage({
14
+ quantity: requests,
15
+ errors: errors > 0 ? errors : undefined
16
+ });
17
+ requests = 0;
18
+ errors = 0;
19
+ }
20
+ }, reqDelay);
21
+ return new Promise(() => { });
22
+ }
23
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAY5C,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAe;IACnE,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,WAAW,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,SAAS,CAAC;aACf,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,EAAE,CAAC;QACb,CAAC,CAAC,CAAA;QAEF,QAAQ,EAAE,CAAC;QAEX,IAAG,QAAQ,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;YACrB,UAAU,EAAE,WAAW,CAAC;gBACpB,QAAQ,EAAE,QAAQ;gBAClB,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;aAC1C,CAAC,CAAA;YAEF,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM,GAAG,CAAC,CAAC;QACf,CAAC;IACL,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEb,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "req-rain",
3
+ "version": "0.1.0",
4
+ "description": "Sends multiple requests to a server.",
5
+ "license": "MIT",
6
+ "author": "Kevin",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "scripts": {
10
+ "start": "node ./dist/index.js",
11
+ "dev": "tsc -w"
12
+ },
13
+ "keywords": [
14
+ "req",
15
+ "request",
16
+ "server",
17
+ "http",
18
+ "ping",
19
+ "threads"
20
+ ],
21
+ "bin": {
22
+ "reqrain": "bin/reqrain"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^25.3.2",
26
+ "typescript": "^5.9.3"
27
+ },
28
+ "dependencies": {
29
+ "commander": "^14.0.3",
30
+ "piscina": "^5.1.4"
31
+ }
32
+ }