@rudderstack/integrations-lib
Version:
A comprehensive TypeScript library providing shared utilities, SDKs, and tools for RudderStack integrations and destinations.
150 lines • 16 kB
JavaScript
;
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=