fix: Calculate job speed using last successful data retrieval timestamp
- Use updated_at (last successful data loop) instead of Date.now() - Speed now reflects actual data retrieval rate, not declining over time - Updated in table column, monitored job view, and stats row - Fall back to Date.now() if updated_at is not available Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -665,9 +665,11 @@ export default function JobsView({ jobs, onSelectJob, isLoadingJob, onRefresh }:
|
|||||||
const isStuck = row.status === 'running' &&
|
const isStuck = row.status === 'running' &&
|
||||||
new Date().getTime() - new Date(row.created_at).getTime() > 10 * 60 * 1000;
|
new Date().getTime() - new Date(row.created_at).getTime() > 10 * 60 * 1000;
|
||||||
|
|
||||||
// For actively running jobs (not stuck), calculate speed from elapsed time
|
// For actively running jobs (not stuck), calculate speed from last successful data retrieval
|
||||||
if (row.status === 'running' && !isStuck && row.started_at && row.reviews_count) {
|
if (row.status === 'running' && !isStuck && row.started_at && row.reviews_count) {
|
||||||
const elapsed = (Date.now() - new Date(row.started_at).getTime()) / 1000;
|
// Use updated_at (last successful data loop) if available, otherwise fall back to Date.now()
|
||||||
|
const endTime = row.updated_at ? new Date(row.updated_at).getTime() : Date.now();
|
||||||
|
const elapsed = (endTime - new Date(row.started_at).getTime()) / 1000;
|
||||||
return elapsed > 0 ? row.reviews_count / elapsed : null;
|
return elapsed > 0 ? row.reviews_count / elapsed : null;
|
||||||
}
|
}
|
||||||
return calculateSpeed(row.reviews_count, row.scrape_time);
|
return calculateSpeed(row.reviews_count, row.scrape_time);
|
||||||
@@ -679,9 +681,11 @@ export default function JobsView({ jobs, onSelectJob, isLoadingJob, onRefresh }:
|
|||||||
const isStuck = isRunning &&
|
const isStuck = isRunning &&
|
||||||
new Date().getTime() - new Date(job.created_at).getTime() > 10 * 60 * 1000;
|
new Date().getTime() - new Date(job.created_at).getTime() > 10 * 60 * 1000;
|
||||||
|
|
||||||
// For actively running jobs (not stuck), show live speed
|
// For actively running jobs (not stuck), show live speed based on last successful data retrieval
|
||||||
if (isRunning && !isStuck && job.started_at && job.reviews_count) {
|
if (isRunning && !isStuck && job.started_at && job.reviews_count) {
|
||||||
const elapsed = (Date.now() - new Date(job.started_at).getTime()) / 1000;
|
// Use updated_at (last successful data loop) if available, otherwise fall back to Date.now()
|
||||||
|
const endTime = job.updated_at ? new Date(job.updated_at).getTime() : Date.now();
|
||||||
|
const elapsed = (endTime - new Date(job.started_at).getTime()) / 1000;
|
||||||
const speed = elapsed > 0 ? job.reviews_count / elapsed : 0;
|
const speed = elapsed > 0 ? job.reviews_count / elapsed : 0;
|
||||||
const isGood = speed >= 1;
|
const isGood = speed >= 1;
|
||||||
const isSlow = speed < 0.5;
|
const isSlow = speed < 0.5;
|
||||||
@@ -696,9 +700,10 @@ export default function JobsView({ jobs, onSelectJob, isLoadingJob, onRefresh }:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For stuck jobs, show frozen speed in red
|
// For stuck jobs, show frozen speed in red (use updated_at for accurate speed)
|
||||||
if (isStuck && job.started_at && job.reviews_count) {
|
if (isStuck && job.started_at && job.reviews_count) {
|
||||||
const elapsed = (Date.now() - new Date(job.started_at).getTime()) / 1000;
|
const endTime = job.updated_at ? new Date(job.updated_at).getTime() : Date.now();
|
||||||
|
const elapsed = (endTime - new Date(job.started_at).getTime()) / 1000;
|
||||||
const speed = elapsed > 0 ? job.reviews_count / elapsed : 0;
|
const speed = elapsed > 0 ? job.reviews_count / elapsed : 0;
|
||||||
return (
|
return (
|
||||||
<span className="font-medium text-red-600">
|
<span className="font-medium text-red-600">
|
||||||
@@ -1371,9 +1376,13 @@ export default function JobsView({ jobs, onSelectJob, isLoadingJob, onRefresh }:
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between mt-1 text-xs text-gray-500">
|
<div className="flex justify-between mt-1 text-xs text-gray-500">
|
||||||
<span>{Math.round(((monitoredJob.reviews_count || 0) / monitoredJob.total_reviews) * 100)}% complete</span>
|
<span>{Math.round(((monitoredJob.reviews_count || 0) / monitoredJob.total_reviews) * 100)}% complete</span>
|
||||||
{monitoredJob.status === 'running' && monitoredJob.reviews_count && monitoredJob.scrape_time && (
|
{monitoredJob.status === 'running' && monitoredJob.reviews_count && monitoredJob.started_at && (
|
||||||
<span>
|
<span>
|
||||||
{(monitoredJob.reviews_count / monitoredJob.scrape_time).toFixed(1)} reviews/sec
|
{(() => {
|
||||||
|
const endTime = monitoredJob.updated_at ? new Date(monitoredJob.updated_at).getTime() : Date.now();
|
||||||
|
const elapsed = (endTime - new Date(monitoredJob.started_at).getTime()) / 1000;
|
||||||
|
return elapsed > 0 ? (monitoredJob.reviews_count / elapsed).toFixed(1) : '0';
|
||||||
|
})()} reviews/sec
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1391,10 +1400,20 @@ export default function JobsView({ jobs, onSelectJob, isLoadingJob, onRefresh }:
|
|||||||
<div className="bg-white rounded-lg p-3 border border-gray-200">
|
<div className="bg-white rounded-lg p-3 border border-gray-200">
|
||||||
<div className="text-xs text-gray-500 mb-1">Speed</div>
|
<div className="text-xs text-gray-500 mb-1">Speed</div>
|
||||||
<div className="text-lg font-semibold text-gray-900">
|
<div className="text-lg font-semibold text-gray-900">
|
||||||
{monitoredJob.reviews_count && monitoredJob.scrape_time
|
{(() => {
|
||||||
? `${(monitoredJob.reviews_count / monitoredJob.scrape_time).toFixed(1)}/s`
|
if (!monitoredJob.reviews_count || !monitoredJob.started_at) return '-';
|
||||||
: '-'
|
// For running jobs, use updated_at; for completed, use scrape_time
|
||||||
}
|
if (monitoredJob.status === 'running') {
|
||||||
|
const endTime = monitoredJob.updated_at ? new Date(monitoredJob.updated_at).getTime() : Date.now();
|
||||||
|
const elapsed = (endTime - new Date(monitoredJob.started_at).getTime()) / 1000;
|
||||||
|
return elapsed > 0 ? `${(monitoredJob.reviews_count / elapsed).toFixed(1)}/s` : '-';
|
||||||
|
}
|
||||||
|
// For completed/partial jobs, use scrape_time if available
|
||||||
|
if (monitoredJob.scrape_time) {
|
||||||
|
return `${(monitoredJob.reviews_count / monitoredJob.scrape_time).toFixed(1)}/s`;
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white rounded-lg p-3 border border-gray-200">
|
<div className="bg-white rounded-lg p-3 border border-gray-200">
|
||||||
|
|||||||
Reference in New Issue
Block a user