Class: ApiKeys::Jobs::UpdateStatsJob
- Inherits:
-
ActiveJob::Base
- Object
- ActiveJob::Base
- ApiKeys::Jobs::UpdateStatsJob
- Includes:
- Logging
- Defined in:
- lib/api_keys/jobs/update_stats_job.rb
Overview
Background job to update API key usage statistics (last_used_at, requests_count). Enqueued by the Authentication concern after a successful request.
Constant Summary collapse
- MAX_FUTURE_CLOCK_SKEW =
5.minutes
Instance Method Summary collapse
-
#perform(api_key_id, timestamp) ⇒ Object
Perform the database updates for the given ApiKey.
Instance Method Details
#perform(api_key_id, timestamp) ⇒ Object
Perform the database updates for the given ApiKey.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/api_keys/jobs/update_stats_job.rb', line 24 def perform(api_key_id, ) api_key = ApiKey.find_by(id: api_key_id) unless api_key log_warn "[ApiKeys::Jobs::UpdateStatsJob] ApiKey not found with ID: #{api_key_id}. Skipping stats update." return end unless .respond_to?(:to_time) log_warn "[ApiKeys::Jobs::UpdateStatsJob] Invalid timestamp for ApiKey ID: #{api_key_id}. Skipping stats update." return end = .to_time if > Time.current + MAX_FUTURE_CLOCK_SKEW log_warn "[ApiKeys::Jobs::UpdateStatsJob] Rejected a timestamp too far in the future." return end log_debug "[ApiKeys::Jobs::UpdateStatsJob] Updating stats for ApiKey ID: #{api_key_id}" # Jobs may execute out of order. Update only when this event is newer so # last_used_at can never regress to an earlier request timestamp. ApiKey .where(id: api_key.id) .where("last_used_at IS NULL OR last_used_at < ?", ) .update_all(last_used_at: ) # Conditionally increment requests_count if configured if ApiKeys.configuration.track_requests_count # Use increment_counter for atomic updates ApiKey.increment_counter(:requests_count, api_key.id) log_debug "[ApiKeys::Jobs::UpdateStatsJob] Incremented requests_count for ApiKey ID: #{api_key_id}" end log_debug "[ApiKeys::Jobs::UpdateStatsJob] Finished updating stats for ApiKey ID: #{api_key_id}" rescue ActiveRecord::ActiveRecordError => error # Log error but don't automatically retry unless configured to do so. # Frequent stats updates might tolerate occasional failures better than endless retries. log_error "[ApiKeys::Jobs::UpdateStatsJob] Failed to update stats for ApiKey ID: #{api_key_id} (#{error.class})." # Depending on ActiveJob adapter, specific retry logic might be needed here # or configured globally. For now, just log. rescue StandardError => error log_error "[ApiKeys::Jobs::UpdateStatsJob] Unexpected error processing ApiKey ID: #{api_key_id} (#{error.class})." # Consider re-raising or using a dead-letter queue strategy depending on job system end |