
Security News
Anthropic Identifies Biased Reasoning and Recklessness as Drivers of Claude’s PyPI Attack
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.
universal-graceful-exit
Advanced tools
Zero-dependency universal lifecycle manager and socket buffer flusher for Node.js
A low-level lifecycle manager for Node.js. Automatically tracks network buffers and guarantees that data sent in fire-and-forget mode (to Redis, RabbitMQ, Postgres, etc.) is not lost when the application exits or on critical errors.
You no longer need to call redis.quit() or channel.close() manually. The package watches system TCP sockets and prevents Node.js from exiting until the internal socket buffer (writableLength) becomes 0.
It works with any type of server natively, and with servers like WebSocketServer register those with trackServer because under the hood they are EventEmitter instances, not native HTTP servers:
import { trackServer } from 'universal-graceful-exit';
const wss = new WebSocketServer({ port: config.port });
trackServer(wss);
Register outbound clients (ioredis, amqplib, pg, ...) with trackClient so they get quit / close / end / disconnect on shutdown:
import { trackClient } from 'universal-graceful-exit';
trackClient(redis);
trackClient(amqpConnection);
Call untrackClient when you close or replace a tracked client. The library keeps a reference to every tracked client until shutdown; if you reconnect for weeks without untracking, those already-closed objects stay in memory. A second quit / close on shutdown is usually harmless; the leak is not.
import { trackClient, untrackClient } from 'universal-graceful-exit';
async function reconnectRedis() {
if (redis) {
await redis.quit();
untrackClient(redis);
}
redis = new Redis(config.redisUrl);
trackClient(redis);
}
The same pattern applies to a pool or request-scoped client you drain yourself (pool.end(), channel.close(), ...): close it, then untrackClient so this library drops its reference.
npm install universal-graceful-exit
Import the package as the very first line of your application:
import 'universal-graceful-exit'; // It intercepts signals and unhandledRejections on its own
import { isStopped } from 'universal-graceful-exit';
import { myRabbitClient } from './db';
async function worker() {
while (!isStopped()) {
// Your business logic
myRabbitClient.sendToQueue('tasks', Buffer.from('data')); // no await!
}
}
import { isStopped, startTask, endTask } from 'universal-graceful-exit';
async function startConsuming(rabbitConn) {
const rabbitChannel = await rabbitConn.createChannel();
await rabbitChannel.prefetch(200);
const { consumerTag } = await rabbitChannel.consume(
'ordered_events',
async msg => {
if (!msg) return;
startTask();
const result = await processEvent(msg.content);
if (msg.properties.replyTo) {
rabbitChannel.sendToQueue(msg.properties.replyTo, Buffer.from(result), {
correlationId: msg.properties.correlationId
});
}
rabbitChannel.ack(msg);
endTask();
if (isStopped()) {
await rabbitChannel.cancel(consumerTag).catch(() => {});
}
},
{ noAck: false }
);
}
If you need to trigger a graceful shutdown from inside your application logic (e.g., an admin route or a critical business workflow), you can emit a custom event on the global process object. This allows you to pass a custom exit code without forcing a hard crash:
import 'universal-graceful-exit';
// Trigger a safe, buffered exit with a custom exit code (e.g., 5)
process.emit('gracefulExit', 5);
Log example of usage with ws and ioredis libraries
[UniversalExit] Received OS signal: SIGINT
[UniversalExit] Clean shutdown initiated. Custom Servers: 1, Native Servers: 1, Sockets: 4
[UniversalExit] Custom server clients: 1
[UniversalExit] currentTasks: 0, currentBytes: 0, customServers: 1, clients: 4
[UniversalExit] Closing client via quit...
[UniversalExit] Closing client via quit...
[UniversalExit] Closing client via quit...
[UniversalExit] Closing client via quit...
[UniversalExit] Scheduling next check #0. Sockets left: 4
[UniversalExit] Native server close event
[UniversalExit] Custom server close event
[WARN] EventServer - Websocket Server closed
[DEBUG] EventServer - Websocket Client Connection closed
[UniversalExit] Socket natively CLOSED. Left in set: 3
[UniversalExit] Socket natively CLOSED. Left in set: 2
[UniversalExit] Socket natively CLOSED. Left in set: 1
[UniversalExit] Socket natively CLOSED. Left in set: 0
[UniversalExit] currentTasks: 0, currentBytes: 0, customServers: 0, clients: 0
[UniversalExit] All buffers, tasks, servers and clients cleared successfully. Exiting cleanly.
[DEBUG] App - Shut down complete!
FAQs
Zero-dependency universal lifecycle manager and socket buffer flusher for Node.js
The npm package universal-graceful-exit receives a total of 190 weekly downloads. As such, universal-graceful-exit popularity was classified as not popular.
We found that universal-graceful-exit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.

Research
/Security News
Malicious Chrome and Firefox extensions target Axiom Trade and Padre users, stealing session tokens and wallet data.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.