ProcessJSON now uses batch processing
(ctx context.Context, uploadID, source string, reader io.Reader, store StoreFunc)
| 458 | |
| 459 | // ProcessJSON now uses batch processing |
| 460 | func ProcessJSON(ctx context.Context, uploadID, source string, reader io.Reader, store StoreFunc) (int, error) { |
| 461 | bufferedReader := bufio.NewReaderSize(reader, DefaultBufferSize) |
| 462 | decoder := json.NewDecoder(bufferedReader) |
| 463 | |
| 464 | var transactions []model.ExternalTransaction |
| 465 | if err := decoder.Decode(&transactions); err != nil { |
| 466 | return 0, err |
| 467 | } |
| 468 | |
| 469 | // Process in batches for better performance |
| 470 | batchSize := DefaultBatchSize |
| 471 | totalProcessed := 0 |
| 472 | |
| 473 | for i := 0; i < len(transactions); i += batchSize { |
| 474 | end := i + batchSize |
| 475 | if end > len(transactions) { |
| 476 | end = len(transactions) |
| 477 | } |
| 478 | |
| 479 | batch := transactions[i:end] |
| 480 | for j := range batch { |
| 481 | batch[j].Source = source |
| 482 | if err := store(ctx, uploadID, batch[j]); err != nil { |
| 483 | return totalProcessed, err |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | totalProcessed += len(batch) |
| 488 | |
| 489 | // Check context periodically |
| 490 | if i%ContextCheckInterval == 0 { |
| 491 | select { |
| 492 | case <-ctx.Done(): |
| 493 | return totalProcessed, ctx.Err() |
| 494 | default: |
| 495 | } |
| 496 | } |
| 497 | } |
| 498 | |
| 499 | return len(transactions), nil |
| 500 | } |
| 501 | |
| 502 | func parseFloat(s string) float64 { |
| 503 | f, err := strconv.ParseFloat(s, 64) |