(
chunk: WorkChunk,
job: ImportJob,
workerId: number,
)
| 503 | } |
| 504 | |
| 505 | private async processDateRangeChunk( |
| 506 | chunk: WorkChunk, |
| 507 | job: ImportJob, |
| 508 | workerId: number, |
| 509 | ): Promise<void> { |
| 510 | const { days } = chunk.data; |
| 511 | let processedInChunk = 0; |
| 512 | let processedDaysWithData = 0; |
| 513 | const totalInChunk = days?.length || 0; |
| 514 | |
| 515 | for (const day of days || []) { |
| 516 | if (!day.heartbeats || day.heartbeats.length === 0) { |
| 517 | processedInChunk++; |
| 518 | |
| 519 | if (processedInChunk % 5 === 0 || processedInChunk === totalInChunk) { |
| 520 | chunk.progress = Math.round((processedInChunk / totalInChunk) * 100); |
| 521 | this.updateJobProgress(job.id); |
| 522 | } |
| 523 | continue; |
| 524 | } |
| 525 | |
| 526 | try { |
| 527 | const userAgents = new Map(); |
| 528 | const processedHeartbeats = day.heartbeats.map((h: any) => |
| 529 | mapHeartbeat( |
| 530 | h, |
| 531 | userAgents, |
| 532 | job.userId, |
| 533 | chunk.data.originalJob.data.exportData?.user.last_plugin, |
| 534 | ), |
| 535 | ); |
| 536 | |
| 537 | await processHeartbeatsByDate(job.userId, processedHeartbeats); |
| 538 | processedInChunk++; |
| 539 | processedDaysWithData++; |
| 540 | chunk.data.processedDays = processedDaysWithData; |
| 541 | |
| 542 | if (processedInChunk % 5 === 0 || processedInChunk === totalInChunk) { |
| 543 | chunk.progress = Math.round((processedInChunk / totalInChunk) * 100); |
| 544 | this.updateJobProgress(job.id); |
| 545 | } |
| 546 | } catch (error) { |
| 547 | handleLog( |
| 548 | `[worker] Worker ${workerId} error processing day ${day.date}: ${error}`, |
| 549 | ); |
| 550 | processedInChunk++; |
| 551 | } |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | private updateJobProgress(jobId: string): void { |
| 556 | const job = activeJobs.get(jobId); |
no test coverage detected