process — argv, env, exit, uncaughtException, SIGINT
process nima?
Siz Node.js skriptini ishga tushirasiz:
node app.js
Operatsion tizim bu skript uchun alohida process (jarayon) yaratadi. Xuddi siz kompyuterda Word ochsangiz — u alohida jarayon bo'lgani kabi. Har bir jarayonning o'z xotirasi, o'z holati bor.
process — Node.js da o'sha joriy jarayonni ifodalovchi global ob'ekt. Uni import qilish shart emas — har qayerda mavjud. U orqali jarayonning hamma narsasini boshqarish mumkin: qanday argumentlar bilan ishga tushirilgan, qanday muhit o'zgaruvchilari bor, qanday to'xtatish kerak.
process.argv — buyruq qatori argumentlari
Tasavvur qiling: siz fayl konvertatsiya qiluvchi skript yozdingiz. Har safar skript ichida fayl nomini o'zgartirish — noqulay. Yaxshisi, terminaldan bering:
node convert.js input.txt output.pdf
process.argv — shu argumentlarni massiv sifatida beradi:
console.log(process.argv);
// [
// '/usr/bin/node', ← [0] node ning o'zi
// '/home/user/convert.js', ← [1] skript fayli
// 'input.txt', ← [2] birinchi argument
// 'output.pdf' ← [3] ikkinchi argument
// ]
Birinchi ikki element har doim bir xil — node va skript yo'li. Sizning argumentlaringiz [2] dan boshlanadi:
const args = process.argv.slice(2);
// ['input.txt', 'output.pdf']
const input = args[0]; // 'input.txt'
const output = args[1]; // 'output.pdf'
if (!input || !output) {
console.error('Ishlatish: node convert.js <input> <output>');
process.exit(1);
}
console.log(`${input} → ${output} ga konvertatsiya qilinmoqda`);
process.env — muhit o'zgaruvchilari
Parol, API kalit, ma'lumotlar bazasi manzili — bularni kod ichiga yozmaslik kerak. Sababi: kod GitHub ga chiqadi, parol oshkor bo'ladi.
Yechim — muhit o'zgaruvchilari (environment variables). Ular operatsion tizim darajasida saqlanadi, kod ichida emas.
# Terminalda o'rnatish:
export DATABASE_URL="postgresql://localhost/mydb"
export JWT_SECRET="super-secret-key"
export PORT=3000
node app.js
Kod ichida o'qish:
const dbUrl = process.env.DATABASE_URL;
const secret = process.env.JWT_SECRET;
const port = process.env.PORT || 3000; // bo'lmasa standart qiymat
console.log(`Server ${port}-portda ishlamoqda`);
Amalda .env fayli ishlatiladi — har safar export yozmaslik uchun:
# .env fayli
DATABASE_URL=postgresql://localhost/mydb
JWT_SECRET=super-secret-key
PORT=3000
// dotenv paketi .env faylini o'qib, process.env ga yuklaydi
require('dotenv').config();
console.log(process.env.DATABASE_URL); // 'postgresql://localhost/mydb'
⚠️
.envfaylini hech qachon GitHub ga chiqarmang..gitignorega qo'shing.
process.exit — jarayonni to'xtatish
process.exit() — jarayonni darhol to'xtatadi. Argument sifatida exit code beriladi:
0— muvaffaqiyatli tugadi1(yoki boshqa nol bo'lmagan son) — xato bilan tugadi
Bu nima uchun muhim? Boshqa skriptlar yoki CI/CD tizimlari exit code ni tekshiradi. 0 bo'lsa — davom etadi. 1 bo'lsa — to'xtaydi, xato deb belgilaydi.
const fs = require('fs');
const configPath = process.argv[2];
if (!configPath) {
console.error('Xato: config fayl yo\'li berilmadi');
process.exit(1); // xato bilan to'xtat
}
if (!fs.existsSync(configPath)) {
console.error(`Xato: ${configPath} fayl topilmadi`);
process.exit(1);
}
console.log('Config yuklandi');
process.exit(0); // muvaffaqiyatli to'xtat
⚠️
process.exit()hamma narsani darhol to'xtatadi — asinxron operatsiyalar ham. Fayl yozilayotgan bo'lsa, ma'lumotlar bazasiga yozilayotgan bo'lsa — hammasi bekor bo'ladi. Shuning uchun faqat haqiqatan kerak bo'lganda ishlatiladi.
process.on('uncaughtException') — ushlanmagan xatolar
Kod ichida try/catch bilan ushlanmagan xato chiqsa — Node.js jarayonni to'xtatadi va stack trace chiqaradi. Bu production da yomon — server o'chib qoladi.
uncaughtException eventi bu xatolarni ushlab qoladi:
process.on('uncaughtException', (err) => {
console.error('Ushlanmagan xato:', err.message);
console.error(err.stack);
// Logga yozish, monitoring ga xabar berish...
process.exit(1); // keyin to'xtatish
});
// Endi bu xato serverni o'chirmaydi:
setTimeout(() => {
throw new Error('Kutilmagan xato!');
}, 1000);
Muhim nuance: uncaughtException dan keyin jarayon noaniq holatda bo'ladi — xotira buzilgan bo'lishi mumkin. Shuning uchun xatoni log qilib, jarayonni to'xtatish kerak. PM2 yoki cluster uni qayta ishga tushiradi.
Asinxron xatolar uchun — unhandledRejection:
process.on('unhandledRejection', (reason, promise) => {
console.error('Ushlanmagan Promise xatosi:', reason);
process.exit(1);
});
// Bu xato ushlanadi:
Promise.reject(new Error('Promise xatosi'));
process.on('SIGINT') va 'SIGTERM' — to'xtatish signallari
Siz terminalda Ctrl+C bosganda — operatsion tizim jarayonga SIGINT signali yuboradi. Standart bo'yicha Node.js darhol to'xtaydi.
Lekin ba'zan to'xtatishdan oldin tozalash kerak: ma'lumotlar bazasi ulanishini yopish, fayllarni saqlash, so'rovlarni tugatish.
const db = require('./database');
// Ctrl+C bosilganda:
process.on('SIGINT', async () => {
console.log('\nTo\'xtatilmoqda...');
await db.close(); // ma'lumotlar bazasini yop
console.log('DB yopildi');
process.exit(0);
});
// Docker/Kubernetes to'xtatganda (SIGTERM):
process.on('SIGTERM', async () => {
console.log('SIGTERM qabul qilindi');
await db.close();
process.exit(0);
});
console.log('Server ishlamoqda. To\'xtatish uchun Ctrl+C');
SIGTERM — kill <pid> buyrug'i yoki Docker stop berganda keladi. Production da har doim SIGTERM ham ushlanadi.
process.cwd va process.chdir
process.cwd() — hozirgi ishchi papka (current working directory). Skript qaysi papkadan ishga tushirilgan.
console.log(process.cwd());
// '/home/user/project' ← node buyrug'i qayerdan ishga tushirilgan
__dirname bilan farqi: __dirname — faylning o'z papkasi. process.cwd() — node qayerdan ishga tushirilgan. Agar siz /home/user dan node project/app.js deb ishga tushirsangiz:
// app.js fayli /home/user/project/ da
console.log(__dirname); // '/home/user/project' ← fayl papkasi
console.log(process.cwd()); // '/home/user' ← ishga tushirilgan papka
Fayl yo'llarini hisoblashda __dirname ishlatiladi — process.cwd() emas.
process.memoryUsage va process.cpuUsage
Monitoring uchun foydali — jarayon qancha resurs sarflayapti:
const mem = process.memoryUsage();
console.log(`RSS: ${(mem.rss / 1024 / 1024).toFixed(1)} MB`);
console.log(`Heap jami: ${(mem.heapTotal / 1024 / 1024).toFixed(1)} MB`);
console.log(`Heap ishlatilgan: ${(mem.heapUsed / 1024 / 1024).toFixed(1)} MB`);
// RSS — jarayon uchun ajratilgan jami xotira
// heapTotal — V8 heap ning jami hajmi
// heapUsed — hozir ishlatilayotgan heap
Tez-tez uchraydigan xatolar
process.exit() ni asinxron operatsiya ichida chaqirish:
process.on('SIGINT', () => {
db.close(); // asinxron — tugamasdan...
process.exit(0); // ...darhol to'xtatiladi
});
// To'g'ri:
process.on('SIGINT', async () => {
await db.close(); // tugashini kut
process.exit(0);
});
uncaughtException dan keyin davom etish:
process.on('uncaughtException', (err) => {
console.error(err);
// process.exit() yo'q — jarayon davom etadi
// Lekin holat noaniq, xotira buzilgan bo'lishi mumkin
});
uncaughtException dan keyin har doim process.exit(1) chaqiriladi.
Xulosa
process — joriy Node.js jarayonini boshqarish uchun global ob'ekt.
| Nima qiladi | |
|---|---|
process.argv |
Buyruq qatori argumentlari |
process.env |
Muhit o'zgaruvchilari (parol, kalit) |
process.exit(code) |
Jarayonni to'xtatish |
uncaughtException |
Ushlanmagan xatolarni tutish |
unhandledRejection |
Ushlanmagan Promise xatolarini tutish |
SIGINT |
Ctrl+C signali |
SIGTERM |
Tizim to'xtatish signali |
process.cwd() |
Hozirgi ishchi papka |
Keyingi dars
21-dars: child_process — exec, spawn, fork