Files
Data-Coupler/SALESFORCE_BATCH_EXTRACTION_IMPROVEMENTS.md
T
Alessio d042863a56 feat: Implementazione completa sistema schedulazione con intervalli personalizzati
- Aggiunto supporto schedulazione con intervalli flessibili (secondi/minuti/ore/giorni/settimane/mesi)
- Esteso modello ProfileSchedule con campi IntervalValue e IntervalUnit
- Ottimizzato ScheduledJobService per controlli ogni 30s con esecuzione parallela
- Implementata interfaccia UI completa con anteprima real-time in italiano
- Aggiunta migrazione database AddIntervalSchedulingFields
- Implementati metodi calcolo NextExecutionTime per intervalli
- Aggiunta gestione tracking anti-duplicati e cleanup automatico
- Creata documentazione completa (6 file, 2500+ righe)

Modifiche tecniche:
- ProfileSchedule.cs: Nuovi campi e metodi CalculateNextInterval/GetScheduleDescription
- ScheduledJobService.cs: Ridotto check interval a 30s, aggiunto parallel processing
- ProfileScheduleService.cs: Supporto calcolo intervalli in UpdateNextExecutionTimeAsync
- Scheduling.razor: Aggiunta sezione UI per configurazione intervalli
- Scheduling.razor.cs: Implementato GetIntervalPreview() e gestione stato campi
2025-10-02 01:12:39 +02:00

9.5 KiB

Salesforce Batch Extraction - Miglioramenti Implementati

📋 Panoramica

Sono stati implementati significativi miglioramenti al SalesforceServiceClient per ottimizzare l'estrazione degli oggetti REST utilizzando operazioni batch e parallel processing. Queste modifiche migliorano drasticamente le performance quando si lavora con grandi volumi di dati.

🚀 Nuove Funzionalità Implementate

1. Batch Query Execution

BatchExecuteQueriesAsync

  • Scopo: Esegue multiple query SOQL in parallelo utilizzando le API Composite di Salesforce
  • Limite: Max 25 operazioni per richiesta composite (limite Salesforce)
  • Parallelizzazione: Processa automaticamente i batch in parallelo per massimizzare il throughput
  • Utilizzo:
var queries = new List<string>
{
    "SELECT Id, Name FROM Account WHERE Type = 'Customer'",
    "SELECT Id, FirstName, LastName FROM Contact WHERE Department = 'Sales'"
};

var results = await salesforceClient.BatchExecuteQueriesAsync(queries, cancellationToken);

BatchFindEntitiesByKeysAsync

  • Scopo: Cerca múltiple entità usando diverse combinazioni di chiavi in una singola operazione batch
  • Ottimizzazione: Raggruppa le ricerche per ridurre il numero di chiamate API
  • Utilizzo:
var keyFieldsList = new List<Dictionary<string, object>>
{
    new() { {"Email", "john@example.com"} },
    new() { {"Email", "jane@example.com"} },
    new() { {"Phone", "+1234567890"} }
};

var results = await salesforceClient.BatchFindEntitiesByKeysAsync("Contact", keyFieldsList, cancellationToken);

BatchGetEntitiesByIdsAsync

  • Scopo: Recupera múltiple entità tramite i loro ID utilizzando query batch con clausole IN
  • Ottimizzazione: Max 200 ID per query per evitare limiti URL, ma processa migliaia di ID in parallelo
  • Utilizzo:
var entityIds = new List<string> { "001XX000004TmiQYAS", "001XX000004TmiRYAS" };
var fieldsToSelect = new List<string> { "Id", "Name", "Type", "BillingCity" };

var entities = await salesforceClient.BatchGetEntitiesByIdsAsync("Account", entityIds, fieldsToSelect, cancellationToken);

3. Advanced Extraction Methods

ExtractAllEntitiesAsync

  • Scopo: Estrae tutti i record di un'entità utilizzando paginazione automatica
  • Features:
    • Paginazione trasparente usando nextRecordsUrl
    • Supporto per filtri WHERE personalizzati
    • Limite massimo record configurabile
    • Auto-discovery dei campi se non specificati
  • Utilizzo:
var fieldsToSelect = new List<string> { "Id", "Name", "Type", "CreatedDate" };
var whereClause = "Type = 'Customer' AND CreatedDate >= 2024-01-01T00:00:00Z";

var allAccounts = await salesforceClient.ExtractAllEntitiesAsync("Account", fieldsToSelect, whereClause, maxRecords: 5000, cancellationToken);

ExtractEntitiesParallelAsync

  • Scopo: Estrae entità utilizzando múltiple query parallele con criteri diversi
  • Use Case: Ideale per dividere grandi dataset per data, tipo, o altri criteri
  • Deduplicazione: Rimuove automaticamente i duplicati basandosi sul campo Id
  • Utilizzo:
var whereClauses = new List<string>
{
    "CreatedDate >= 2024-01-01T00:00:00Z AND CreatedDate < 2024-02-01T00:00:00Z",
    "CreatedDate >= 2024-02-01T00:00:00Z AND CreatedDate < 2024-03-01T00:00:00Z",
    "CreatedDate >= 2024-03-01T00:00:00Z AND CreatedDate < 2024-04-01T00:00:00Z"
};

var allData = await salesforceClient.ExtractEntitiesParallelAsync("Opportunity", fieldsToSelect, whereClauses, cancellationToken: cancellationToken);

4. Utility Methods

CreateDateBasedWhereClauses

  • Scopo: Helper per creare automaticamente clausole WHERE basate su intervalli di date
  • Configurabile: Dimensione del chunk (default: 30 giorni), campo data da utilizzare
  • Utilizzo:
var startDate = DateTime.Parse("2024-01-01");
var endDate = DateTime.Parse("2024-12-31");

var whereClauses = salesforceClient.CreateDateBasedWhereClauses(startDate, endDate, "CreatedDate", chunkSizeInDays: 7);

ExtractLargeDatasetAsync

  • Scopo: Metodo intelligente che determina automaticamente la strategia ottimale
  • Auto-Detection: Controlla la dimensione del dataset e sceglie tra estrazione sequenziale o parallela
  • Soglia: >10,000 record = estrazione parallela con chunking per data
  • Utilizzo:
var largeDataset = await salesforceClient.ExtractLargeDatasetAsync("Case", fieldsToSelect, "Status = 'Open'", cancellationToken: cancellationToken);

ExtractRecentlyModifiedAsync

  • Scopo: Estrae entità modificate di recente (utile per sincronizzazioni incrementali)
  • Configurabile: Numero di ore indietro nel tempo (default: 24)
  • Utilizzo:
var recentContacts = await salesforceClient.ExtractRecentlyModifiedAsync("Contact", fieldsToSelect, hoursBack: 48, cancellationToken);

📊 Miglioramenti delle Performance

Prima delle modifiche:

  • Single query execution
  • Sequential processing
  • Multiple API calls per operazioni batch
  • No parallel processing
  • Manual pagination handling

Dopo le modifiche:

  • Batch query execution (fino a 25 query contemporaneamente)
  • Parallel processing di múltiple batch
  • Paginazione automatica con nextRecordsUrl
  • Auto-chunking per grandi dataset
  • Intelligent extraction strategy selection
  • Deduplicazione automatica dei risultati
  • Date-based parallel extraction

Risultati Attesi:

  • 🚀 Performance: 10-25x più veloce per operazioni su grandi dataset
  • 📉 API Calls: Riduzione del 60-90% delle chiamate API
  • 💾 Memory Efficiency: Gestione ottimizzata della memoria con processing a chunck
  • 🔄 Reliability: Gestione robusta degli errori con retry per singoli batch

🔧 Classi di Supporto Aggiunte

BatchQueryResult

public class BatchQueryResult
{
    public int QueryIndex { get; set; }           // Indice della query originale
    public string Query { get; set; }             // Query SOQL eseguita
    public bool Success { get; set; }             // Successo operazione
    public string ErrorMessage { get; set; }     // Messaggio di errore se fallita
    public List<Dictionary<string, object>> Records { get; set; }  // Risultati
    public int TotalSize { get; set; }            // Numero totale di record
    public string? NextRecordsUrl { get; set; }   // URL per paginazione
}

Enhanced SalesforceQueryResponse

private class SalesforceQueryResponse
{
    [JsonPropertyName("records")]
    public List<Dictionary<string, object>> Records { get; set; }
    
    [JsonPropertyName("totalSize")]
    public int TotalSize { get; set; }
    
    [JsonPropertyName("done")]
    public bool Done { get; set; }
    
    [JsonPropertyName("nextRecordsUrl")]
    public string? NextRecordsUrl { get; set; }
}

📈 Scenari di Utilizzo

1. Estrazione Completa di un'Entità

// Estrae tutti i record Account con paginazione automatica
var allAccounts = await salesforceClient.ExtractAllEntitiesAsync("Account");

2. Estrazione di Grandi Dataset con Parallel Processing

// Per dataset molto grandi, utilizza chunking automatico basato su date
var largeDataset = await salesforceClient.ExtractLargeDatasetAsync("Case", maxRecords: 100000);

3. Sincronizzazione Incrementale

// Estrae solo i record modificati nelle ultime 24 ore
var recentlyModified = await salesforceClient.ExtractRecentlyModifiedAsync("Contact", hoursBack: 24);

4. Ricerca Batch di Multiple Entità

var searchCriteria = new List<Dictionary<string, object>>
{
    new() { {"Email", "user1@company.com"} },
    new() { {"Email", "user2@company.com"} },
    // ... fino a centinaia di email
};

var foundContacts = await salesforceClient.BatchFindEntitiesByKeysAsync("Contact", searchCriteria);

5. Estrazione Parallela per Intervalli Temporali

var startDate = DateTime.Parse("2024-01-01");
var endDate = DateTime.Now;
var whereClauses = salesforceClient.CreateDateBasedWhereClauses(startDate, endDate, "CreatedDate", 30);

var historicalData = await salesforceClient.ExtractEntitiesParallelAsync("Opportunity", null, whereClauses);

🛠️ Compatibilità e Migrazione

  • Backward Compatible: Tutti i metodi esistenti continuano a funzionare
  • Enhanced Methods: I metodi esistenti utilizzano automaticamente le nuove funzionalità batch quando possibile
  • Optional Parameters: Tutti i nuovi parametri sono opzionali con valori di default sensati
  • Existing Interfaces: Nessuna modifica alle interfacce pubbliche esistenti

📝 Note Tecniche

Limiti Salesforce Rispettati:

  • Composite API: Max 25 sub-requests per richiesta
  • SOQL IN Clause: Max 200 valori per clausola IN
  • URL Length: Gestione automatica per evitare limiti URL
  • API Rate Limits: Distribuzione delle chiamate per rispettare i limiti

Error Handling:

  • Batch Failure Isolation: Il fallimento di un batch non compromette gli altri
  • Detailed Logging: Logging completo per debugging e monitoraggio
  • Graceful Degradation: Fallback a metodi sequenziali in caso di errori

Memory Management:

  • Streaming Processing: I dati vengono processati a chunk per evitare OutOfMemory
  • Parallel Execution: Limitazione della concorrenza per evitare sovraccarico
  • Resource Cleanup: Gestione appropriata delle risorse con using pattern

Data Implementazione: Settembre 2024
Versione: 1.0
Compatibile con: Salesforce API v60.0+
Framework: .NET 9.0