Optimize runner manager heartbeat to skip unnecessary database updates

What does this MR do and why?

Optimizes the Ci::RunnerManager#heartbeat method to prevent unnecessary database writes when runner attributes haven't changed.

Runners send frequent heartbeat requests, and previously every heartbeat would trigger a database update even when only contacted_at changed (which is tracked in Redis cache). This MR adds a changed? check before calling update_columns, reducing database load for large runner fleets with stable configurations.

Changes:

  • Modified app/models/ci/runner_manager.rb: Added && changed? condition to skip update_columns when no attributes have changed
  • Added test coverage for no-change scenarios, cache-only updates, and partial attribute changes

References

Screenshots or screen recordings

N/A - Backend optimization

How to set up and validate locally

  1. Run the new specs to verify the optimization:
   bundle exec rspec spec/models/ci/runner_manager_spec.rb
  1. To observe the behavior in development:
   # In rails console
   runner = Ci::Runner.first
   manager = runner.runner_managers.first
   
   # Heartbeat with no changes - should not update DB
   manager.heartbeat({ version: manager.version })
   
   # Heartbeat with changes - should update DB
   manager.heartbeat({ version: '16.0.0' })

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Pedro Pombeiro

Merge request reports

Loading