2025-09-08 14:46:30 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
# Daily Track Generation Job
|
|
|
|
|
#
|
|
|
|
|
# Automatically processes new location points for all active/trial users on a regular schedule.
|
|
|
|
|
# This job runs periodically (recommended: every 2-4 hours) to generate tracks from newly
|
|
|
|
|
# received location data.
|
|
|
|
|
#
|
|
|
|
|
# Process:
|
|
|
|
|
# 1. Iterates through all active or trial users
|
|
|
|
|
# 2. For each user, finds the timestamp of their last track's end_at
|
|
|
|
|
# 3. Checks if there are new points since that timestamp
|
|
|
|
|
# 4. If new points exist, triggers parallel track generation using the existing system
|
|
|
|
|
# 5. Uses the parallel generator with 'daily' mode for optimal performance
|
|
|
|
|
#
|
|
|
|
|
# The job leverages the existing parallel track generation infrastructure,
|
|
|
|
|
# ensuring consistency with bulk operations while providing automatic daily processing.
|
2025-09-08 15:15:41 -04:00
|
|
|
|
2025-09-08 14:46:30 -04:00
|
|
|
class Tracks::DailyGenerationJob < ApplicationJob
|
|
|
|
|
queue_as :tracks
|
|
|
|
|
|
|
|
|
|
def perform
|
|
|
|
|
User.active_or_trial.find_each do |user|
|
2025-12-30 11:33:56 -05:00
|
|
|
next if user.points_count&.zero?
|
2025-09-08 14:46:30 -04:00
|
|
|
|
|
|
|
|
process_user_daily_tracks(user)
|
|
|
|
|
rescue StandardError => e
|
|
|
|
|
ExceptionReporter.call(e, "Failed to process daily tracks for user #{user.id}")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
def process_user_daily_tracks(user)
|
2025-09-10 15:46:03 -04:00
|
|
|
start_timestamp = start_timestamp(user)
|
2025-09-08 14:46:30 -04:00
|
|
|
|
2025-09-10 15:46:03 -04:00
|
|
|
return unless user.points.where('timestamp >= ?', start_timestamp).exists?
|
2025-09-08 14:46:30 -04:00
|
|
|
|
|
|
|
|
Tracks::ParallelGeneratorJob.perform_later(
|
|
|
|
|
user.id,
|
2025-10-31 14:29:20 -04:00
|
|
|
start_at: Time.zone.at(start_timestamp),
|
|
|
|
|
end_at: Time.current,
|
2025-09-08 14:46:30 -04:00
|
|
|
mode: 'daily'
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2025-09-10 15:46:03 -04:00
|
|
|
def start_timestamp(user)
|
|
|
|
|
last_end = user.tracks.maximum(:end_at)&.to_i
|
|
|
|
|
return last_end + 1 if last_end
|
2025-09-08 15:09:28 -04:00
|
|
|
|
2025-09-10 15:46:03 -04:00
|
|
|
user.points.minimum(:timestamp) || 1.week.ago.to_i
|
2025-09-08 14:46:30 -04:00
|
|
|
end
|
|
|
|
|
end
|