UNPKG

cs-element

Version:

Advanced reactive data management library with state machines, blueprints, persistence, compression, networking, and multithreading support

830 lines (707 loc) 27.7 kB
# Расширенная система Batch операций Система Batch операций CSElement предоставляет мощные инструменты для эффективного выполнения массовых операций с поддержкой различных стратегий выполнения, управления зависимостями и мониторинга прогресса. ## 🎯 Основные возможности ### Стратегии выполнения - **Sequential** - последовательное выполнение операций - **Parallel** - параллельное выполнение независимых операций - **Mixed** - комбинированный подход с учетом зависимостей - **Priority-based** - выполнение по приоритетам ### Управление зависимостями - **Автоматическое разрешение** - построение графа зависимостей - **Циклическая проверка** - обнаружение циклических зависимостей - **Условные зависимости** - зависимости на основе результатов - **Динамические зависимости** - изменение зависимостей во время выполнения ### Обработка ошибок - **Fail-fast** - остановка при первой ошибке - **Collect-errors** - сбор всех ошибок - **Retry** - повторные попытки с настраиваемой логикой - **Rollback** - откат изменений при ошибках ## 🚀 Быстрый старт ### Базовая настройка ```typescript import { BatchManager, BatchExecutionStrategy } from 'cs-element'; // Создание менеджера batch операций const batchManager = new BatchManager({ defaultStrategy: BatchExecutionStrategy.MIXED, maxConcurrency: 10, enableRetry: true, enableRollback: true, timeout: 30000 }); // Создание batch const batchId = batchManager.createBatch({ name: 'User Data Processing', description: 'Массовая обработка пользовательских данных', executionStrategy: BatchExecutionStrategy.PARALLEL, maxConcurrency: 5, errorHandling: 'collect-errors' }); ``` ### Простые операции ```typescript // Добавление операций в batch const operations = [ { id: 'validate-users', name: 'Валидация пользователей', operation: async (context) => { const users = await loadUsers(); const validUsers = []; const errors = []; for (const user of users) { try { await validateUser(user); validUsers.push(user); } catch (error) { errors.push({ user: user.id, error: error.message }); } } return { validUsers, errors }; }, priority: 1, timeout: 10000 }, { id: 'process-orders', name: 'Обработка заказов', operation: async (context) => { const orders = await loadPendingOrders(); const processedOrders = []; for (const order of orders) { await processOrder(order); processedOrders.push(order.id); } return { processedOrders }; }, dependencies: ['validate-users'], // Зависит от валидации пользователей priority: 2 }, { id: 'send-notifications', name: 'Отправка уведомлений', operation: async (context) => { const processedOrders = context.getResult('process-orders').processedOrders; const notifications = []; for (const orderId of processedOrders) { await sendOrderNotification(orderId); notifications.push(orderId); } return { notifications }; }, dependencies: ['process-orders'], priority: 3 } ]; // Добавление операций в batch for (const operation of operations) { batchManager.addOperation(batchId, operation); } ``` ### Выполнение batch ```typescript // Подписка на события batchManager.onProgress(batchId, (progress) => { console.log(`Прогресс: ${progress.percentage}% (${progress.completed}/${progress.total})`); console.log(`Текущая операция: ${progress.currentOperation}`); }); batchManager.onOperationComplete(batchId, (operationId, result) => { console.log(`Операция завершена: ${operationId}`, result); }); batchManager.onError(batchId, (operationId, error) => { console.error(`Ошибка в операции ${operationId}:`, error); }); // Выполнение batch try { const result = await batchManager.executeBatch(batchId); console.log('Batch выполнен успешно:', { totalOperations: result.totalOperations, successfulOperations: result.successfulOperations, failedOperations: result.failedOperations, executionTime: result.executionTime, results: result.results }); } catch (error) { console.error('Ошибка выполнения batch:', error); // Получение детальной информации об ошибках const errors = batchManager.getErrors(batchId); console.log('Детали ошибок:', errors); } ``` ## 📚 Подробное руководство ### Стратегии выполнения #### Sequential - Последовательное выполнение ```typescript const sequentialBatch = batchManager.createBatch({ name: 'Sequential Processing', executionStrategy: BatchExecutionStrategy.SEQUENTIAL, // Операции выполняются строго по порядку preserveOrder: true }); // Операции будут выполнены одна за другой batchManager.addOperation(sequentialBatch, { id: 'step1', operation: async () => { console.log('Шаг 1: Подготовка данных'); await sleep(1000); return { data: 'prepared' }; } }); batchManager.addOperation(sequentialBatch, { id: 'step2', operation: async (context) => { const step1Result = context.getResult('step1'); console.log('Шаг 2: Обработка данных', step1Result); await sleep(1000); return { processed: true }; } }); batchManager.addOperation(sequentialBatch, { id: 'step3', operation: async (context) => { const step2Result = context.getResult('step2'); console.log('Шаг 3: Сохранение результата', step2Result); await sleep(1000); return { saved: true }; } }); ``` #### Parallel - Параллельное выполнение ```typescript const parallelBatch = batchManager.createBatch({ name: 'Parallel Processing', executionStrategy: BatchExecutionStrategy.PARALLEL, maxConcurrency: 8, // Максимум 8 операций одновременно loadBalancing: true // Балансировка нагрузки }); // Независимые операции, которые могут выполняться параллельно const dataSources = ['users', 'products', 'orders', 'reviews']; dataSources.forEach(source => { batchManager.addOperation(parallelBatch, { id: `process-${source}`, name: `Обработка ${source}`, operation: async () => { console.log(`Начало обработки ${source}`); const data = await loadDataFromSource(source); const processed = await processData(data); console.log(`Завершена обработка ${source}`); return { source, count: processed.length }; }, estimatedDuration: 5000, // Оценка времени выполнения weight: source === 'orders' ? 2 : 1 // Вес операции для балансировки }); }); ``` #### Mixed - Смешанная стратегия ```typescript const mixedBatch = batchManager.createBatch({ name: 'Mixed Strategy Processing', executionStrategy: BatchExecutionStrategy.MIXED, maxConcurrency: 6, optimizeExecution: true // Автоматическая оптимизация порядка выполнения }); // Операции с различными зависимостями batchManager.addOperation(mixedBatch, { id: 'init', name: 'Инициализация', operation: async () => { await initializeSystem(); return { initialized: true }; }, priority: 10 // Высокий приоритет }); // Параллельные операции после инициализации ['cache', 'database', 'external-api'].forEach(service => { batchManager.addOperation(mixedBatch, { id: `setup-${service}`, name: `Настройка ${service}`, operation: async () => { await setupService(service); return { service, ready: true }; }, dependencies: ['init'], // Зависят от инициализации canRunInParallel: true // Могут выполняться параллельно друг с другом }); }); // Финальная операция после всех настроек batchManager.addOperation(mixedBatch, { id: 'finalize', name: 'Финализация', operation: async (context) => { const setupResults = [ context.getResult('setup-cache'), context.getResult('setup-database'), context.getResult('setup-external-api') ]; await finalizeSystem(setupResults); return { finalized: true }; }, dependencies: ['setup-cache', 'setup-database', 'setup-external-api'] }); ``` ### Управление зависимостями #### Условные зависимости ```typescript batchManager.addOperation(batchId, { id: 'conditional-operation', name: 'Условная операция', operation: async (context) => { const initResult = context.getResult('init'); if (initResult.requiresSpecialProcessing) { await performSpecialProcessing(); return { specialProcessed: true }; } else { await performStandardProcessing(); return { standardProcessed: true }; } }, conditionalDependencies: [ { operationId: 'special-setup', condition: (context) => { const initResult = context.getResult('init'); return initResult.requiresSpecialProcessing; } } ] }); ``` #### Динамические зависимости ```typescript batchManager.addOperation(batchId, { id: 'dynamic-processor', name: 'Динамический процессор', operation: async (context) => { const dataResult = context.getResult('load-data'); const dataChunks = chunkData(dataResult.data, 100); // Динамическое создание операций для каждого чанка const chunkOperations = dataChunks.map((chunk, index) => ({ id: `process-chunk-${index}`, name: `Обработка чанка ${index}`, operation: async () => { return await processChunk(chunk); } })); // Добавление операций в batch динамически for (const op of chunkOperations) { context.addDynamicOperation(op); } return { chunksCreated: chunkOperations.length }; }, dependencies: ['load-data'], allowDynamicOperations: true }); ``` ### Обработка ошибок и восстановление #### Retry механизм ```typescript batchManager.addOperation(batchId, { id: 'unreliable-operation', name: 'Ненадежная операция', operation: async () => { // Операция, которая может временно не работать const success = Math.random() > 0.3; if (!success) { throw new Error('Временная ошибка сервиса'); } return { success: true }; }, retry: { maxAttempts: 3, delay: 1000, // 1 секунда между попытками backoff: 'exponential', // Экспоненциальная задержка retryCondition: (error) => { // Повторять только для временных ошибок return error.message.includes('Временная ошибка'); } } }); ``` #### Rollback операции ```typescript batchManager.addOperation(batchId, { id: 'database-update', name: 'Обновление базы данных', operation: async (context) => { const transaction = await database.beginTransaction(); try { await database.updateUsers(userData); await database.updateOrders(orderData); await transaction.commit(); return { updated: true, rollbackData: { transactionId: transaction.id, originalData: { users: userData, orders: orderData } } }; } catch (error) { await transaction.rollback(); throw error; } }, rollback: async (context, result) => { if (result && result.rollbackData) { console.log('Выполнение rollback для database-update'); await database.restoreFromBackup(result.rollbackData.originalData); } }, critical: true // Критическая операция, требующая rollback при ошибках }); ``` #### Компенсационные операции ```typescript batchManager.addOperation(batchId, { id: 'send-emails', name: 'Отправка email уведомлений', operation: async (context) => { const users = context.getResult('process-users').users; const sentEmails = []; for (const user of users) { await sendEmail(user.email, 'Welcome!'); sentEmails.push(user.email); } return { sentEmails }; }, compensation: async (context, result) => { // Компенсационная операция при rollback if (result && result.sentEmails) { console.log('Отправка компенсационных email'); for (const email of result.sentEmails) { await sendEmail(email, 'Operation Cancelled'); } } } }); ``` ## ⚙️ Мониторинг и аналитика ### Детальный мониторинг ```typescript // Настройка детального мониторинга batchManager.enableDetailedMonitoring(batchId, { trackMemoryUsage: true, trackCpuUsage: true, trackNetworkIO: true, sampleInterval: 1000 // Каждую секунду }); // Получение метрик в реальном времени batchManager.onMetricsUpdate(batchId, (metrics) => { console.log('Метрики batch:', { memoryUsage: metrics.memoryUsage, cpuUsage: metrics.cpuUsage, activeOperations: metrics.activeOperations, queuedOperations: metrics.queuedOperations, averageOperationTime: metrics.averageOperationTime }); }); // Получение детального отчета после выполнения const detailedReport = await batchManager.getDetailedReport(batchId); console.log('Детальный отчет:', { executionTimeline: detailedReport.timeline, resourceUsage: detailedReport.resourceUsage, bottlenecks: detailedReport.bottlenecks, recommendations: detailedReport.recommendations }); ``` ### Визуализация выполнения ```typescript // Генерация визуализации выполнения batch const visualization = await batchManager.generateVisualization(batchId, { format: 'html', // 'html', 'svg', 'ascii' includeTimeline: true, includeDependencyGraph: true, includeMetrics: true }); // Сохранение визуализации import fs from 'fs'; fs.writeFileSync(`batch-${batchId}-report.html`, visualization.content); console.log('Визуализация сохранена в файл'); ``` ### Аналитика производительности ```typescript // Анализ производительности batch const performanceAnalysis = await batchManager.analyzePerformance(batchId); console.log('Анализ производительности:', { totalExecutionTime: performanceAnalysis.totalTime, parallelizationEfficiency: performanceAnalysis.parallelizationEfficiency, resourceUtilization: performanceAnalysis.resourceUtilization, criticalPath: performanceAnalysis.criticalPath, optimizationSuggestions: performanceAnalysis.suggestions }); // Сравнение с предыдущими выполнениями const comparison = await batchManager.compareWithHistory(batchId); console.log('Сравнение с историей:', { performanceImprovement: comparison.performanceChange, reliabilityChange: comparison.reliabilityChange, trends: comparison.trends }); ``` ## 🔍 Продвинутые возможности ### Batch композиция ```typescript // Создание составного batch из других batch const masterBatch = batchManager.createCompositeBatch({ name: 'Master Data Processing Pipeline', subBatches: [ { batchId: 'data-ingestion-batch', condition: () => true, // Всегда выполнять timeout: 60000 }, { batchId: 'data-processing-batch', condition: (context) => { const ingestionResult = context.getSubBatchResult('data-ingestion-batch'); return ingestionResult.recordCount > 0; }, timeout: 120000 }, { batchId: 'data-export-batch', condition: (context) => { const processingResult = context.getSubBatchResult('data-processing-batch'); return processingResult.success; }, timeout: 30000 } ], errorHandling: 'fail-fast', rollbackStrategy: 'reverse-order' // Rollback в обратном порядке }); await batchManager.executeCompositeBatch(masterBatch); ``` ### Streaming batch операции ```typescript // Создание streaming batch для обработки больших объемов данных const streamingBatch = batchManager.createStreamingBatch({ name: 'Large Dataset Processing', chunkSize: 1000, maxMemoryUsage: '512MB', backpressureHandling: true }); // Добавление streaming операции batchManager.addStreamingOperation(streamingBatch, { id: 'process-large-dataset', name: 'Обработка большого датасета', dataSource: async function* () { // Генератор данных for (let i = 0; i < 1000000; i++) { yield await loadDataRecord(i); } }, processor: async (chunk) => { // Обработка чанка данных return await processDataChunk(chunk); }, sink: async (processedChunk) => { // Сохранение обработанных данных await saveProcessedData(processedChunk); }, chunkSize: 100, maxConcurrency: 4 }); // Выполнение streaming batch const streamResult = await batchManager.executeStreamingBatch(streamingBatch); console.log('Streaming обработка завершена:', { totalRecords: streamResult.totalRecords, processedChunks: streamResult.processedChunks, averageChunkTime: streamResult.averageChunkTime, throughput: streamResult.recordsPerSecond }); ``` ### Batch шаблоны ```typescript // Создание переиспользуемых шаблонов batch const dataProcessingTemplate = batchManager.createBatchTemplate({ name: 'Data Processing Template', description: 'Стандартный шаблон для обработки данных', parameters: { dataSource: { type: 'string', required: true }, outputFormat: { type: 'string', default: 'json' }, enableValidation: { type: 'boolean', default: true } }, operations: [ { id: 'load-data', name: 'Загрузка данных', operation: async (context, params) => { return await loadData(params.dataSource); } }, { id: 'validate-data', name: 'Валидация данных', operation: async (context, params) => { if (params.enableValidation) { const data = context.getResult('load-data'); return await validateData(data); } return { valid: true, skipped: true }; }, dependencies: ['load-data'], conditional: (params) => params.enableValidation }, { id: 'process-data', name: 'Обработка данных', operation: async (context, params) => { const data = context.getResult('load-data'); return await processData(data, params.outputFormat); }, dependencies: ['validate-data'] } ] }); // Использование шаблона const batchFromTemplate = await batchManager.createBatchFromTemplate( dataProcessingTemplate, { dataSource: '/path/to/data.csv', outputFormat: 'parquet', enableValidation: true } ); await batchManager.executeBatch(batchFromTemplate); ``` ## 🔧 Интеграция с другими системами ### React интеграция ```typescript import React, { useState, useEffect } from 'react'; import { useBatchManager } from 'cs-element/react'; function BatchMonitoringComponent() { const batchManager = useBatchManager(); const [activeBatches, setActiveBatches] = useState([]); const [selectedBatch, setSelectedBatch] = useState(null); useEffect(() => { const interval = setInterval(() => { setActiveBatches(batchManager.getActiveBatches()); }, 1000); return () => clearInterval(interval); }, [batchManager]); const handleCreateBatch = async () => { const batchId = batchManager.createBatch({ name: 'User Created Batch', executionStrategy: 'parallel' }); // Добавление операций... await batchManager.executeBatch(batchId); }; return ( <div className="batch-monitoring"> <h2>Мониторинг Batch операций</h2> <button onClick={handleCreateBatch}> Создать новый Batch </button> <div className="active-batches"> <h3>Активные Batch</h3> {activeBatches.map(batch => ( <div key={batch.id} className="batch-item"> <h4>{batch.name}</h4> <div className="progress"> <div className="progress-bar" style={{ width: `${batch.progress.percentage}%` }} /> <span>{batch.progress.percentage}%</span> </div> <div className="batch-stats"> <span>Операций: {batch.progress.completed}/{batch.progress.total}</span> <span>Время: {batch.executionTime}ms</span> <span>Статус: {batch.status}</span> </div> </div> ))} </div> </div> ); } ``` ### Node.js Worker интеграция ```typescript // Интеграция с Node.js Worker Threads import { Worker, isMainThread, parentPort } from 'worker_threads'; if (isMainThread) { // Главный поток const batchManager = new BatchManager({ useWorkerThreads: true, workerPoolSize: 4 }); batchManager.addOperation(batchId, { id: 'cpu-intensive-operation', name: 'CPU интенсивная операция', operation: async (context) => { // Операция будет выполнена в worker thread return await batchManager.executeInWorker('cpu-worker.js', { data: context.getData(), operation: 'heavy-computation' }); }, useWorker: true, workerScript: './cpu-worker.js' }); } else { // Worker поток parentPort.on('message', async (message) => { const { data, operation } = message; let result; switch (operation) { case 'heavy-computation': result = await performHeavyComputation(data); break; default: throw new Error(`Неизвестная операция: ${operation}`); } parentPort.postMessage({ result }); }); } ``` ## 🚨 Устранение неполадок ### Общие проблемы **Проблема:** Медленное выполнение параллельных операций ```typescript // ❌ Неправильно - слишком много параллельных операций const batch = batchManager.createBatch({ maxConcurrency: 50 // Может перегрузить систему }); // ✅ Правильно - оптимальное количество const batch = batchManager.createBatch({ maxConcurrency: Math.min(8, os.cpus().length * 2), loadBalancing: true }); ``` **Проблема:** Зависания из-за циклических зависимостей ```typescript // ❌ Неправильно - циклическая зависимость batchManager.addOperation(batchId, { id: 'op1', dependencies: ['op2'] }); batchManager.addOperation(batchId, { id: 'op2', dependencies: ['op1'] }); // ✅ Правильно - проверка зависимостей const dependencyCheck = batchManager.validateDependencies(batchId); if (!dependencyCheck.isValid) { console.error('Циклические зависимости:', dependencyCheck.cycles); } ``` ### Диагностика производительности ```typescript // Диагностика производительности batch const diagnostics = await batchManager.diagnoseBatch(batchId); console.log('Диагностика batch:', { bottlenecks: diagnostics.bottlenecks, resourceUtilization: diagnostics.resourceUtilization, optimizationSuggestions: diagnostics.suggestions, estimatedImprovements: diagnostics.estimatedImprovements }); // Профилирование отдельных операций const operationProfile = await batchManager.profileOperation('slow-operation'); console.log('Профиль операции:', { averageExecutionTime: operationProfile.averageTime, memoryUsage: operationProfile.memoryUsage, cpuUsage: operationProfile.cpuUsage, recommendations: operationProfile.recommendations }); ``` Расширенная система Batch операций CSElement предоставляет мощные инструменты для эффективной обработки массовых операций с полным контролем над выполнением, мониторингом и оптимизацией производительности.