UNPKG

@rudderstack/integrations-lib

Version:

A comprehensive TypeScript library providing shared utilities, SDKs, and tools for RudderStack integrations and destinations.

150 lines 16 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable require-await */ const cluster_1 = __importDefault(require("cluster")); const manager_1 = require("./manager"); const logger = __importStar(require("../logger")); async function normalExample() { const manager = new manager_1.ClusterManager({ numWorkers: 2, pingFrequency: 1000, // Check every second pingTimeout: 5000, // 5 seconds for a worker to respond shutdownTimeout: 5000, // 5 seconds for graceful shutdown primaryFn: async () => { setTimeout(() => { logger.info('Primary process shutting down...'); manager.shutdown('manual shutdown'); }, 10000); }, primaryShutdownFn: async (signal) => { logger.info(`Primary process shutting down due to signal: ${signal}`); }, workerFn: async () => { // Simulate some work setInterval(() => { logger.info(`Worker ${cluster_1.default.worker?.id} is doing work`); }, 1000); }, workerShutdownFn: async (signal) => { logger.info(`Worker ${cluster_1.default.worker?.id} shutting down due to signal: ${signal}`); }, }); await manager.start(); } async function stuckExample() { let stuckCounter = 0; const manager = new manager_1.ClusterManager({ numWorkers: 2, pingFrequency: 1000, // Check every second pingTimeout: 5000, // 5 seconds for a worker to respond shutdownTimeout: 5000, // 5 seconds for graceful shutdown stuckWorkerRespawnFunc: (worker) => { stuckCounter += 1; if (stuckCounter > 3) { logger.info(`Stuck worker detected: ${worker.id}. Not respawning anymore.`); return false; // Stop respawning after 3 stuck workers } logger.info(`Stuck worker detected: ${worker.id}. Respawning...`); return true; // Respawn the worker }, primaryFn: async () => { logger.info('Primary process started'); }, primaryShutdownFn: async (signal) => { logger.info(`Primary process shutting down due to signal: ${signal}`); }, workerFn: async () => { logger.info(`Worker ${cluster_1.default.worker?.id} will simulate being stuck`); // eslint-disable-next-line no-constant-condition while (true) { // Simulate a stuck worker } }, workerShutdownFn: async (signal) => { logger.info(`Worker ${cluster_1.default.worker?.id} shutting down due to signal: ${signal}`); }, }); await manager.start(); } async function killExample() { const manager = new manager_1.ClusterManager({ numWorkers: 2, pingFrequency: 1000, // Check every second pingTimeout: 5000, // 5 seconds for a worker to respond shutdownTimeout: 5000, // 5 seconds for graceful shutdown restartMaxTimes: 3, // Restart a worker up to 3 times primaryFn: async () => { logger.info('Primary process started'); }, primaryShutdownFn: async (signal) => { logger.info(`Primary process shutting down due to signal: ${signal}`); }, workerFn: async () => { logger.info(`Worker ${cluster_1.default.worker?.id} started and will crash after 5 seconds`); // eslint-disable-next-line no-constant-condition setTimeout(() => { logger.info(`Killing worker ${cluster_1.default.worker?.id} process`); process.exit(1); // Simulate a worker crash }, 5000); // Kill the worker after 5 seconds }, workerShutdownFn: async (signal) => { logger.info(`Worker ${cluster_1.default.worker?.id} shutting down due to signal: ${signal}`); }, }); await manager.start(); } // to run use: npx ts-node src/cluster/examples.ts [normal|stuck|kill] if (require.main === module) { const mode = process.argv[2] || 'normal'; let run; if (mode === 'stuck') { run = stuckExample; } else if (mode === 'kill') { run = killExample; } else { run = normalExample; } run().catch((err) => { logger.error(err); process.exit(1); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhhbXBsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2x1c3Rlci9leGFtcGxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGtDQUFrQztBQUNsQyxzREFBOEI7QUFDOUIsdUNBQTJDO0FBQzNDLGtEQUFvQztBQUVwQyxLQUFLLFVBQVUsYUFBYTtJQUMxQixNQUFNLE9BQU8sR0FBRyxJQUFJLHdCQUFjLENBQUM7UUFDakMsVUFBVSxFQUFFLENBQUM7UUFDYixhQUFhLEVBQUUsSUFBSSxFQUFFLHFCQUFxQjtRQUMxQyxXQUFXLEVBQUUsSUFBSSxFQUFFLG9DQUFvQztRQUN2RCxlQUFlLEVBQUUsSUFBSSxFQUFFLGtDQUFrQztRQUN6RCxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDcEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7Z0JBQ2hELE9BQU8sQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUN0QyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDWixDQUFDO1FBQ0QsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNuQixxQkFBcUI7WUFDckIsV0FBVyxDQUFDLEdBQUcsRUFBRTtnQkFDZixNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsaUJBQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzVELENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNYLENBQUM7UUFDRCxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7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c2FibGUgcmVxdWlyZS1hd2FpdCAqL1xuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3Rlcic7XG5pbXBvcnQgeyBDbHVzdGVyTWFuYWdlciB9IGZyb20gJy4vbWFuYWdlcic7XG5pbXBvcnQgKiBhcyBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuYXN5bmMgZnVuY3Rpb24gbm9ybWFsRXhhbXBsZSgpIHtcbiAgY29uc3QgbWFuYWdlciA9IG5ldyBDbHVzdGVyTWFuYWdlcih7XG4gICAgbnVtV29ya2VyczogMixcbiAgICBwaW5nRnJlcXVlbmN5OiAxMDAwLCAvLyBDaGVjayBldmVyeSBzZWNvbmRcbiAgICBwaW5nVGltZW91dDogNTAwMCwgLy8gNSBzZWNvbmRzIGZvciBhIHdvcmtlciB0byByZXNwb25kXG4gICAgc2h1dGRvd25UaW1lb3V0OiA1MDAwLCAvLyA1IHNlY29uZHMgZm9yIGdyYWNlZnVsIHNodXRkb3duXG4gICAgcHJpbWFyeUZuOiBhc3luYyAoKSA9PiB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1ByaW1hcnkgcHJvY2VzcyBzaHV0dGluZyBkb3duLi4uJyk7XG4gICAgICAgIG1hbmFnZXIuc2h1dGRvd24oJ21hbnVhbCBzaHV0ZG93bicpO1xuICAgICAgfSwgMTAwMDApO1xuICAgIH0sXG4gICAgcHJpbWFyeVNodXRkb3duRm46IGFzeW5jIChzaWduYWwpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGBQcmltYXJ5IHByb2Nlc3Mgc2h1dHRpbmcgZG93biBkdWUgdG8gc2lnbmFsOiAke3NpZ25hbH1gKTtcbiAgICB9LFxuICAgIHdvcmtlckZuOiBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBTaW11bGF0ZSBzb21lIHdvcmtcbiAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFdvcmtlciAke2NsdXN0ZXIud29ya2VyPy5pZH0gaXMgZG9pbmcgd29ya2ApO1xuICAgICAgfSwgMTAwMCk7XG4gICAgfSxcbiAgICB3b3JrZXJTaHV0ZG93bkZuOiBhc3luYyAoc2lnbmFsKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgV29ya2VyICR7Y2x1c3Rlci53b3JrZXI/LmlkfSBzaHV0dGluZyBkb3duIGR1ZSB0byBzaWduYWw6ICR7c2lnbmFsfWApO1xuICAgIH0sXG4gIH0pO1xuICBhd2FpdCBtYW5hZ2VyLnN0YXJ0KCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHN0dWNrRXhhbXBsZSgpIHtcbiAgbGV0IHN0dWNrQ291bnRlciA9IDA7XG4gIGNvbnN0IG1hbmFnZXIgPSBuZXcgQ2x1c3Rlck1hbmFnZXIoe1xuICAgIG51bVdvcmtlcnM6IDIsXG4gICAgcGluZ0ZyZXF1ZW5jeTogMTAwMCwgLy8gQ2hlY2sgZXZlcnkgc2Vjb25kXG4gICAgcGluZ1RpbWVvdXQ6IDUwMDAsIC8vIDUgc2Vjb25kcyBmb3IgYSB3b3JrZXIgdG8gcmVzcG9uZFxuICAgIHNodXRkb3duVGltZW91dDogNTAwMCwgLy8gNSBzZWNvbmRzIGZvciBncmFjZWZ1bCBzaHV0ZG93blxuICAgIHN0dWNrV29ya2VyUmVzcGF3bkZ1bmM6ICh3b3JrZXIpID0+IHtcbiAgICAgIHN0dWNrQ291bnRlciArPSAxO1xuICAgICAgaWYgKHN0dWNrQ291bnRlciA+IDMpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFN0dWNrIHdvcmtlciBkZXRlY3RlZDogJHt3b3JrZXIuaWR9LiBOb3QgcmVzcGF3bmluZyBhbnltb3JlLmApO1xuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFN0b3AgcmVzcGF3bmluZyBhZnRlciAzIHN0dWNrIHdvcmtlcnNcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5pbmZvKGBTdHVjayB3b3JrZXIgZGV0ZWN0ZWQ6ICR7d29ya2VyLmlkfS4gUmVzcGF3bmluZy4uLmApO1xuICAgICAgcmV0dXJuIHRydWU7IC8vIFJlc3Bhd24gdGhlIHdvcmtlclxuICAgIH0sXG4gICAgcHJpbWFyeUZuOiBhc3luYyAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbygnUHJpbWFyeSBwcm9jZXNzIHN0YXJ0ZWQnKTtcbiAgICB9LFxuICAgIHByaW1hcnlTaHV0ZG93bkZuOiBhc3luYyAoc2lnbmFsKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgUHJpbWFyeSBwcm9jZXNzIHNodXR0aW5nIGRvd24gZHVlIHRvIHNpZ25hbDogJHtzaWduYWx9YCk7XG4gICAgfSxcbiAgICB3b3JrZXJGbjogYXN5bmMgKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYFdvcmtlciAke2NsdXN0ZXIud29ya2VyPy5pZH0gd2lsbCBzaW11bGF0ZSBiZWluZyBzdHVja2ApO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgLy8gU2ltdWxhdGUgYSBzdHVjayB3b3JrZXJcbiAgICAgIH1cbiAgICB9LFxuICAgIHdvcmtlclNodXRkb3duRm46IGFzeW5jIChzaWduYWwpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGBXb3JrZXIgJHtjbHVzdGVyLndvcmtlcj8uaWR9IHNodXR0aW5nIGRvd24gZHVlIHRvIHNpZ25hbDogJHtzaWduYWx9YCk7XG4gICAgfSxcbiAgfSk7XG4gIGF3YWl0IG1hbmFnZXIuc3RhcnQoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24ga2lsbEV4YW1wbGUoKSB7XG4gIGNvbnN0IG1hbmFnZXIgPSBuZXcgQ2x1c3Rlck1hbmFnZXIoe1xuICAgIG51bVdvcmtlcnM6IDIsXG4gICAgcGluZ0ZyZXF1ZW5jeTogMTAwMCwgLy8gQ2hlY2sgZXZlcnkgc2Vjb25kXG4gICAgcGluZ1RpbWVvdXQ6IDUwMDAsIC8vIDUgc2Vjb25kcyBmb3IgYSB3b3JrZXIgdG8gcmVzcG9uZFxuICAgIHNodXRkb3duVGltZW91dDogNTAwMCwgLy8gNSBzZWNvbmRzIGZvciBncmFjZWZ1bCBzaHV0ZG93blxuICAgIHJlc3RhcnRNYXhUaW1lczogMywgLy8gUmVzdGFydCBhIHdvcmtlciB1cCB0byAzIHRpbWVzXG4gICAgcHJpbWFyeUZuOiBhc3luYyAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbygnUHJpbWFyeSBwcm9jZXNzIHN0YXJ0ZWQnKTtcbiAgICB9LFxuICAgIHByaW1hcnlTaHV0ZG93bkZuOiBhc3luYyAoc2lnbmFsKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgUHJpbWFyeSBwcm9jZXNzIHNodXR0aW5nIGRvd24gZHVlIHRvIHNpZ25hbDogJHtzaWduYWx9YCk7XG4gICAgfSxcbiAgICB3b3JrZXJGbjogYXN5bmMgKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYFdvcmtlciAke2NsdXN0ZXIud29ya2VyPy5pZH0gc3RhcnRlZCBhbmQgd2lsbCBjcmFzaCBhZnRlciA1IHNlY29uZHNgKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbyhgS2lsbGluZyB3b3JrZXIgJHtjbHVzdGVyLndvcmtlcj8uaWR9IHByb2Nlc3NgKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpOyAvLyBTaW11bGF0ZSBhIHdvcmtlciBjcmFzaFxuICAgICAgfSwgNTAwMCk7IC8vIEtpbGwgdGhlIHdvcmtlciBhZnRlciA1IHNlY29uZHNcbiAgICB9LFxuICAgIHdvcmtlclNodXRkb3duRm46IGFzeW5jIChzaWduYWwpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGBXb3JrZXIgJHtjbHVzdGVyLndvcmtlcj8uaWR9IHNodXR0aW5nIGRvd24gZHVlIHRvIHNpZ25hbDogJHtzaWduYWx9YCk7XG4gICAgfSxcbiAgfSk7XG4gIGF3YWl0IG1hbmFnZXIuc3RhcnQoKTtcbn1cblxuLy8gdG8gcnVuIHVzZTogbnB4IHRzLW5vZGUgc3JjL2NsdXN0ZXIvZXhhbXBsZXMudHMgW25vcm1hbHxzdHVja3xraWxsXVxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIGNvbnN0IG1vZGUgPSBwcm9jZXNzLmFyZ3ZbMl0gfHwgJ25vcm1hbCc7XG4gIGxldCBydW47XG4gIGlmIChtb2RlID09PSAnc3R1Y2snKSB7XG4gICAgcnVuID0gc3R1Y2tFeGFtcGxlO1xuICB9IGVsc2UgaWYgKG1vZGUgPT09ICdraWxsJykge1xuICAgIHJ1biA9IGtpbGxFeGFtcGxlO1xuICB9IGVsc2Uge1xuICAgIHJ1biA9IG5vcm1hbEV4YW1wbGU7XG4gIH1cbiAgcnVuKCkuY2F0Y2goKGVycikgPT4ge1xuICAgIGxvZ2dlci5lcnJvcihlcnIpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfSk7XG59XG4iXX0=