ProcessTransactionInBatches processes transactions in batches or streams them based on the provided mode. It starts a tracing span, initializes worker pools, fetches transactions, and processes them concurrently. Parameters: - ctx context.Context: The context for the operation. - parentTransactionI
(ctx context.Context, parentTransactionID string, amount *big.Int, maxWorkers int, streamMode bool, gt getTxns, tw transactionWorker)
| 486 | // - []*model.Transaction: A slice of pointers to the processed Transaction models. |
| 487 | // - error: An error if the transactions could not be processed. |
| 488 | func (l *LedgerForge) ProcessTransactionInBatches(ctx context.Context, parentTransactionID string, amount *big.Int, maxWorkers int, streamMode bool, gt getTxns, tw transactionWorker) ([]*model.Transaction, error) { |
| 489 | // Start a tracing span |
| 490 | ctx, span := tracer.Start(ctx, "ProcessTransactionInBatches") |
| 491 | defer span.End() |
| 492 | |
| 493 | batchSize := l.Config().Transaction.BatchSize |
| 494 | maxQueueSize := l.Config().Transaction.MaxQueueSize |
| 495 | |
| 496 | // Slice to collect all processed transactions and errors |
| 497 | var allTxns []*model.Transaction |
| 498 | var allErrors []error |
| 499 | var mu sync.Mutex // Mutex to protect shared resources |
| 500 | |
| 501 | // Create channels for jobs and results |
| 502 | jobs := make(chan *model.Transaction, maxQueueSize) |
| 503 | results := make(chan BatchJobResult, maxQueueSize) |
| 504 | |
| 505 | // Initialize worker pool |
| 506 | var wg sync.WaitGroup |
| 507 | for w := 1; w <= maxWorkers; w++ { |
| 508 | wg.Add(1) |
| 509 | go tw(ctx, jobs, results, &wg, amount) |
| 510 | } |
| 511 | |
| 512 | // Ensure the results channel is closed once all workers are done |
| 513 | go func() { |
| 514 | wg.Wait() |
| 515 | close(results) |
| 516 | }() |
| 517 | |
| 518 | if !streamMode { |
| 519 | // Start a goroutine to process results |
| 520 | done := make(chan struct{}) |
| 521 | go processResults(results, &mu, &allTxns, &allErrors, done) |
| 522 | |
| 523 | // Fetch and process transactions in batches concurrently |
| 524 | errChan := make(chan error, 1) |
| 525 | go fetchTransactions(ctx, parentTransactionID, batchSize, gt, jobs, errChan) |
| 526 | |
| 527 | // Wait for all processing to complete |
| 528 | select { |
| 529 | case err := <-errChan: |
| 530 | span.RecordError(err) |
| 531 | return allTxns, err |
| 532 | case <-done: |
| 533 | } |
| 534 | |
| 535 | if len(allErrors) > 0 { |
| 536 | // Log errors and return a combined error |
| 537 | for _, err := range allErrors { |
| 538 | logrus.Errorf("Error during processing: %v", err) |
| 539 | span.RecordError(err) |
| 540 | } |
| 541 | return allTxns, fmt.Errorf("error occurred during processing: %v", allErrors) |
| 542 | } |
| 543 | |
| 544 | span.AddEvent("Processed all transactions in batches") |
| 545 | return allTxns, nil |