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
Markdown
# Расширенная система 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 предоставляет мощные инструменты для эффективной обработки массовых операций с полным контролем над выполнением, мониторингом и оптимизацией производительности.