HelloEngineersHelloEngineers
Log inSign up
FeedExploreMessagesJobs
Back to Discuss

Node.js High Level Coding Interview Question #14

0
Interview

Technology: Node.js

Coding Task: Create a task scheduler.

Requirements:

  • Write clean and scalable code
  • Explain project architecture
  • Handle edge cases
  • Optimize performance
  • Add security best practices

Bonus: Explain how you would deploy this project in production.

#nodejs#javascript#backend
Priyanshu Mishra

Priyanshu Mishra

Founder of Helloengineers

61mo ago

1 Answer

0

High-Level Task Scheduler in Node.js (Using Redis & BullMQ) To build a truly clean, scalable, and production-ready task scheduler in Node.js, relying solely on set timeout or in-memory cron packages (node-cron) is a fundamental anti-pattern because they don't scale across multiple server instances. The industry-standard architecture utilizes a Message Broker / Redis-backed Queue (like Bull MQ ) This ensures persistence, distributed processing, and graceful failure handling. 1. Project Architecture Overview Producer: Accepts the task (via API) and pushes it to the Redis queue with metadata (delay, priority, retries). Redis (Data Store): Acts as the in-memory persistence layer holding the scheduled and active jobs. Worker / Consumer: Listens to the Redis queue, processes jobs based on concurrency limits, and handles execution logic. 2. The Code Implementation const { Queue, Worker } = require('bullmq'); const IORedis = require('ioredis'); require('dotenv').config();

// Initialize Redis Connection const redisConnection = new IORedis(process.env.REDIS_URL, { maxRetriesPerRequest: null, enableReadyCheck: false });

// Create the Task Queue const taskQueue = new Queue('enterprise-scheduler', { connection: redisConnection });

/**

  • PRODUCER: Function to schedule tasks securely */ async function scheduleTask(jobName, payload, delayInMs = 0) { try { // Input Validation (Security Best Practice) if (!payload || typeof payload !== 'object') { throw new Error("Invalid payload structure."); }

    const job = await taskQueue.add(jobName, payload, { delay: delayInMs, attempts: 3, // Edge case: Automatic retries backoff: { type: 'exponential', delay: 2000 }, // Exponential backoff for rate limits removeOnComplete: true, // Performance: Clear memory removeOnFail: false // Keep failed jobs for auditing }); console.log(`[Scheduled] Job ${job.id} will run after ${delayInMs}ms`); return job.id;

    } catch (error) { console.error([Scheduling Error]: ${error.message}); } }

/**

  • WORKER / CONSUMER: Processing tasks with concurrency limits */ const worker = new Worker('enterprise-scheduler', async job => { console.log([Processing] Job ${job.id} | Type: ${job.name});

    // Simulate heavy task execution (e.g., sending emails, DB updates) return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.1) return reject(new Error("Simulated API failure")); resolve({ success: true, timestamp: Date.now() }); }, 1000); }); }, { connection: redisConnection, concurrency: 10, // Performance: Process 10 jobs concurrently per instance limiter: { max: 100, // Security/Rate Limiting: Max 100 jobs duration: 1000 // per 1 second to avoid overwhelming third-party APIs } });

// EDGE CASES: Event Listeners for graceful handling worker.on('failed', (job, err) => { console.error([Failed] Job ${job.id} failed after retries: ${err.message}); // Alerting logic goes here (e.g., Send to Sentry/Slack) });

worker.on('stalled', (jobId) => { console.warn([Stalled] Job ${jobId} stalled. Event loop might be blocked.); });

// Example Usage scheduleTask('send-welcome-email', { userId: '12345' }, 5000);

  1. Handling Edge Cases Transient Failures: Implemented attempts:3 with an exponential backoff strategy so the scheduler gracefully handles temporary network glitches. Stalled Jobs: The worker actively listens for 'stalled' events, which prevents memory leaks if a process crashes mid-execution.

Duplicate Processing: By leveraging Redis, BullMQ ensures atomic locks, guaranteeing that a scheduled task is executed exactly once, even if multiple Node.js instances are running. 4. Performance Optimization Concurrency Control: The worker is set to concurrency: 10, preventing a massive influx of scheduled tasks from choking the Node.js single-threaded event loop. Memory Management: Implemented removeOnComplete: true to prevent Redis memory bloat from successful historical jobs. 5. Security Best Practices Rate Limiting: Added a built-in rate limiter (max: 100 per 1000ms) inside the worker to prevent DDoS-ing downstream services or third-party APIs. Input Sanitization: The producer strictly validates the incoming payload before allowing it into the Redis store, preventing injection attacks. Credential Masking: Redis connection strings and API keys are strictly maintained in a .env file, outside the codebase. 6. Bonus: Production Deployment Strategy To deploy this architecture securely and optimally in production: Containerization: Dockerize the Node.js application and the Redis instance. Use a docker-compose.yml for local staging and Kubernetes (K8s) for production scaling. Process Management: Instead of running just node app.js, deploy using PM2 in cluster mode (pm2 start worker.js -i max). This spins up multiple worker processes utilizing all CPU cores. Managed Redis: Do not run a local Redis container in production. Use a managed service like AWS ElastiCache or Redis Enterprise for built-in high availability, backups, and failover. Monitoring: Deploy bull-board (a UI dashboard for BullMQ) on a separate, strictly authenticated admin route to visually monitor queue health, retry failed jobs manually, and track latency metrics.

VIVEK KUMAR OJHAVIVEK KUMAR OJHA1mo ago

Your Answer

Sign in to post an answer

Related

0
Interview
Node.js High Level Coding Interview Question #2

Technology: Node.js Coding Task: Create a real-time chat application. Requirements: - Write clean and scalable code - Explain proje…

nodejsjavascriptbackend
Priyanshu MishraPriyanshu Mishra1mo ago0 answers
0
Interview
Node.js High Level Coding Interview Question #3

Technology: Node.js Coding Task: Implement JWT authentication system. Requirements: - Write clean and scalable code - Explain proje…

nodejsjavascriptbackend
Priyanshu MishraPriyanshu Mishra1mo ago0 answers
0
Interview
Node.js High Level Coding Interview Question #4

Technology: Node.js Coding Task: Build a file upload system. Requirements: - Write clean and scalable code - Explain project archit…

nodejsjavascriptbackend
Priyanshu MishraPriyanshu Mishra1mo ago0 answers
0
Interview
Node.js High Level Coding Interview Question #5

Technology: Node.js Coding Task: Create a pagination API. Requirements: - Write clean and scalable code - Explain project architect…

nodejsjavascriptbackend
Priyanshu MishraPriyanshu Mishra1mo ago0 answers
0
Interview
Node.js High Level Coding Interview Question #6

Technology: Node.js Coding Task: Implement rate limiting middleware. Requirements: - Write clean and scalable code - Explain projec…

nodejsjavascriptbackend
Priyanshu MishraPriyanshu Mishra1mo ago0 answers