@qrvey/process-controller
v1.0.0-661
Published
General Process Controller for managing and monitoring job lifecycle with statistics
Readme
@qrvey/process-controller
General Process Controller for managing and monitoring job lifecycle with detailed statistics tracking.
Features
- Singleton Pattern: Ensures only one instance manages all processes
- Job Lifecycle Management: Register and deregister jobs with automatic tracking
- Statistics Tracking: Automatic calculation of job execution times, averages, and more
- Graceful Shutdown: Handles shutdown requests while waiting for running jobs to complete
- Instance States: ACTIVE, SHUTDOWN_IN_PROGRESS, and INACTIVE states
- Configurable Logging: Custom logger support with enable/disable option
- Event Callbacks: Hooks for job registration, deregistration, and status changes
- Utility Methods: Check job existence, count jobs, get individual jobs, and more
- TypeScript Support: Full TypeScript type definitions included
- Modular Architecture: Well-organized code structure with separate modules
Installation
```bash npm install @qrvey/process-controller
or
yarn add @qrvey/process-controller ```
Usage
Basic Example
```typescript import { GeneralProcessController, INSTANCE_STATUS, WORKER_STATUS } from '@qrvey/process-controller';
// Initialize the controller (do this once at application startup) const controller = GeneralProcessController.initialize();
// Get the controller instance anywhere in your code const gpc = GeneralProcessController.getInstance();
// Register a job gpc.register('job-123', { userId: '456', operation: 'data-processing' });
// Do your work... await processData();
// Deregister the job when complete gpc.deregister('job-123');
// Get current statistics const stats = gpc.getFormattedStatistics(); console.log(stats); // Output: // { // totalJobsInProgress: 0, // totalJobsCount: 1, // totalJobsTime: "2.45 s", // averageJobTime: "2.45 s", // maxJobTime: "2.45 s", // minJobTime: "2.45 s", // startTime: "2025-12-16T10:30:00.000Z", // endTime: "2025-12-16T10:30:02.450Z" // } ```
Advanced Configuration
```typescript import { GeneralProcessController } from '@qrvey/process-controller';
// Initialize with custom configuration const controller = GeneralProcessController.initialize({ // Disable console logging enableLogging: false,
// Or provide custom logger
logger: {
log: (msg) => myLogger.info(msg),
warn: (msg) => myLogger.warn(msg),
error: (msg) => myLogger.error(msg),
},
// Callbacks for events
onJobRegister: (pid, payload) => {
console.log(\`Job \${pid} started with\`, payload);
},
onJobDeregister: (pid, duration) => {
console.log(\`Job \${pid} completed in \${duration}ms\`);
},
onStatusChange: (oldStatus, newStatus) => {
console.log(\`Status changed: \${oldStatus} -> \${newStatus}\`);
},}); ```
Graceful Shutdown
```typescript import { GeneralProcessController, INSTANCE_STATUS } from '@qrvey/process-controller';
const gpcInstance = GeneralProcessController.getInstance();
// Handle shutdown signals ['SIGTERM', 'SIGINT'].forEach(signal => { process.on(signal, async () => { console.log(`${signal} signal received.`);
// Trigger GPC shutdown
gpcInstance.shutdown(\`\${signal}_SIGNAL\`);
// Wait until all the processes are finished
while (gpcInstance.getStatus() !== INSTANCE_STATUS.INACTIVE) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log(\`\${signal} signal processed.\`);
process.exit(0);
});}); ```
Use in Lambda Functions
```typescript import { GeneralProcessController } from '@qrvey/process-controller';
// Initialize once (cold start) const controller = GeneralProcessController.initialize({ enableLogging: process.env.ENABLE_LOGGING === 'true', });
export const handler = async (event: any) => { const jobId = event.jobId;
try {
// Register the job
controller.register(jobId, { event });
// Process the event
const result = await processEvent(event);
return {
statusCode: 200,
body: JSON.stringify(result)
};
} finally {
// Always deregister
controller.deregister(jobId);
}}; ```
Utility Methods
```typescript const controller = GeneralProcessController.getInstance();
// Check instance status if (controller.isActive()) { // Safe to register jobs }
// Get job count const activeJobs = controller.getJobCount();
// Check if specific job exists if (controller.hasJob('job-123')) { console.log('Job is still running'); }
// Get job details const job = controller.getJob('job-123'); if (job) { console.log('Job payload:', job.payload); console.log('Started at:', job.ts); }
// Get raw statistics (in milliseconds) const rawStats = controller.getStatistics();
// Reset statistics (keeps running jobs) controller.resetStatistics();
// Get complete process list const list = controller.getList(); console.log(list); // { // instanceId: "xyz123", // instanceStatus: "ACTIVE", // workerStatus: "BUSY", // workerDetails: [...], // statistics: {...} // } ```
API Reference
Static Methods
`static initialize(config?: ProcessControllerConfig): GeneralProcessController`
Initializes and returns the singleton instance. Safe to call multiple times.
`static getInstance(): GeneralProcessController`
Gets the singleton instance. Throws error if not initialized.
`static resetInstance(): void`
Resets the singleton instance (useful for testing).
Instance Management
`getInstanceId(): string`
Returns the unique instance identifier.
`getStatus(): INSTANCE_STATUS`
Returns the current instance status (ACTIVE, SHUTDOWN_IN_PROGRESS, or INACTIVE).
`start(): void`
Starts the controller (called automatically on initialization).
`shutdown(source?: string): void`
Initiates graceful shutdown. Rejects new jobs and waits for current jobs to complete.
Status Checks
`isActive(): boolean`
Returns true if the instance is active and accepting jobs.
`isShuttingDown(): boolean`
Returns true if the instance is shutting down.
`isInactive(): boolean`
Returns true if the instance is inactive.
Job Management
`register(pid: string, payload?: Record<string, any>): void`
Registers a new job with the given process ID and optional payload. Throws error if PID already exists or if controller is not active.
`deregister(pid: string): void`
Deregisters a job and updates statistics.
`hasJob(pid: string): boolean`
Returns true if a job with the given PID exists.
`getJob(pid: string): JobItem | undefined`
Returns the job item for the given PID, or undefined if not found.
`getJobCount(): number`
Returns the number of currently running jobs.
Statistics
`getStatistics(): Statistics`
Returns raw statistics with time values in milliseconds.
`getFormattedStatistics(): FormattedStatistics`
Returns formatted statistics with human-readable time values.
`resetStatistics(): void`
Resets all statistics (does not affect running jobs).
`getList(): ProcessList`
Returns complete information about instance status, workers, and statistics.
Types
```typescript enum INSTANCE_STATUS { ACTIVE = 'ACTIVE', SHUTDOWN_IN_PROGRESS = 'SHUTDOWN_IN_PROGRESS', INACTIVE = 'INACTIVE', }
enum WORKER_STATUS { IDLE = 'IDLE', BUSY = 'BUSY', }
interface JobItem { pid: string; ts: string; payload: Record<string, any>; }
interface Statistics { totalJobsCount: number; totalJobsTime: number; // in milliseconds averageJobTime: number; // in milliseconds maxJobTime: number; // in milliseconds minJobTime: number; // in milliseconds startTime: number | null; // timestamp endTime: number | null; // timestamp }
interface FormattedStatistics { totalJobsInProgress: number; totalJobsCount: number; totalJobsTime: string; // formatted as "X.XX s" averageJobTime: string; maxJobTime: string; minJobTime: string; startTime: string | null; // ISO string endTime: string | null; // ISO string }
interface ProcessList { instanceId: string; instanceStatus: string; workerStatus: string; workerDetails: JobItem[]; statistics: FormattedStatistics; }
interface ProcessControllerConfig { logger?: { log?: (...args: any[]) => void; warn?: (...args: any[]) => void; error?: (...args: any[]) => void; }; enableLogging?: boolean; onJobRegister?: (pid: string, payload: Record<string, any>) => void; onJobDeregister?: (pid: string, duration: number) => void; onStatusChange?: (oldStatus: string, newStatus: string) => void; } ```
Project Structure
``` src/ ├── constants/ # Enums and constants │ └── index.ts ├── types/ # TypeScript interfaces and types │ └── index.ts ├── utils/ # Utility functions │ ├── logger.ts │ ├── formatters.ts │ └── index.ts ├── GeneralProcessController.ts # Main controller class └── index.ts # Public API exports ```
License
MIT
Keywords
- qrvey
- process-controller
- job-manager
- graceful-shutdown
- statistics
- singleton
- worker-management
- lifecycle-management
