UNPKG

fib-flow

Version:

A robust workflow management system for fibjs with task orchestration, state management, and distributed execution capabilities

155 lines (140 loc) 6.67 kB
/** * PostgreSQL-specific database adapter implementation * Extends BaseDBAdapter with PostgreSQL-specific schema and optimizations */ const BaseDBAdapter = require('./base'); const createLogger = require('../logger'); // Create logger for PostgreSQL adapter operations const logger = createLogger('fib-flow'); /** * PostgreSQL adapter for task persistence * Uses native PostgreSQL features and includes indexes for optimal query performance */ class PSQLAdapter extends BaseDBAdapter { constructor(config, poolSize = 5) { logger.info(`[PSQLAdapter] Initializing with config:`, config); super(config, poolSize); } /** * Initialize PostgreSQL-specific schema * Creates tasks table with appropriate column types and indexes * * Table Structure: * - Task identification and basic info: * - id: BIGSERIAL primary key * - name: Task type name, used to match with registered handlers * - type: Task type (async: one-time, cron: recurring) * - priority: Task priority for execution ordering (-20 to 20, higher runs first) * - payload: JSON encoded task parameters and data * - created_at: Task creation timestamp (Unix seconds) * - tag: Task tag for categorization * * - Task execution status and results: * - status: Current task state * - next_run_time: Next scheduled execution time (Unix seconds) * - last_active_time: Last time task reported activity (Unix seconds) * - result: JSON encoded task execution result * - error: Error message if task failed * * - Task execution settings: * - timeout: Task execution timeout in seconds * - retry_count: Number of retry attempts made * - max_retries: Maximum number of retry attempts allowed * - retry_interval: Delay between retry attempts in seconds * - cron_expr: Cron expression for recurring tasks * * - Workflow relationships: * - root_id: ID of the root task in workflow * - parent_id: ID of the parent task * - total_children: Total number of child tasks * - completed_children: Number of completed child tasks * * - Worker information: * - worker_id: ID of the worker that executed the task * - start_time: Timestamp when task started execution (Unix seconds) * * Indexes: * - idx_fib_flow_tasks_status_priority_next_run_time: B-tree index for task scheduling * - idx_fib_flow_tasks_name: B-tree index for task type lookups * - idx_fib_flow_tasks_parent_status: B-tree index for workflow management * - idx_fib_flow_tasks_tag_name_status: B-tree index for task statistics */ setup() { logger.notice(`[PSQLAdapter] Setting up database schema`); try { this.pool(conn => { logger.notice(`[PSQLAdapter] Creating tasks table if not exists`); conn.execute(` CREATE TABLE IF NOT EXISTS fib_flow_tasks ( id BIGSERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, type VARCHAR(10) NOT NULL, priority INTEGER DEFAULT 0, payload JSONB, created_at BIGINT, tag VARCHAR(255), status VARCHAR(20) NOT NULL, next_run_time BIGINT NOT NULL, last_active_time BIGINT, result JSONB, error TEXT, stage INTEGER DEFAULT 0, timeout INTEGER DEFAULT 60, retry_count INTEGER DEFAULT 0, max_retries INTEGER DEFAULT 3, retry_interval INTEGER DEFAULT 0, cron_expr VARCHAR(100), root_id BIGINT, parent_id BIGINT, total_children INTEGER DEFAULT 0, completed_children INTEGER DEFAULT 0, worker_id VARCHAR(255), start_time BIGINT ); -- Task scheduling index: Optimizes high-frequency task claiming queries -- Uses partial index to improve query performance CREATE INDEX IF NOT EXISTS idx_task_scheduling ON fib_flow_tasks(status, next_run_time, priority DESC) WHERE status = 'pending'; -- Timeout detection index: Only indexes running tasks CREATE INDEX IF NOT EXISTS idx_task_timeout ON fib_flow_tasks(last_active_time) WHERE status = 'running'; -- Workflow index: Supports parent-child relationship queries -- Uses INCLUDE to add commonly accessed fields to reduce table lookups CREATE INDEX IF NOT EXISTS idx_task_workflow ON fib_flow_tasks(parent_id, status) INCLUDE (completed_children, total_children) WHERE parent_id IS NOT NULL; -- Task statistics index: Optimizes tag-based queries -- Uses B-tree index for exact matches and range scans CREATE INDEX IF NOT EXISTS idx_task_stats ON fib_flow_tasks(tag, name, status); -- Task result index: Optimizes JSONB queries CREATE INDEX IF NOT EXISTS idx_task_payload ON fib_flow_tasks USING GIN (payload jsonb_path_ops) WHERE payload IS NOT NULL; `); logger.info(`[PSQLAdapter] Database schema setup completed successfully`); }); } catch (error) { logger.error(`[PSQLAdapter] Failed to setup database schema:`, error); throw error; } } /** * Get the ID of the last inserted row in PostgreSQL * Uses PostgreSQL's lastval() function to retrieve the last value from a sequence * * @protected * @param {Object} conn - Database connection object * @param {Object} rs - Result set from the previous insert operation * @returns {number} The ID of the last inserted row * @throws {Error} If lastval() fails or no sequence has been used in the current session */ _getLastInsertedId(conn, rs) { const rs1 = conn.execute('SELECT lastval()'); return rs1[0].lastval; } } module.exports = PSQLAdapter;