From 6fbff026eb1ad7727db48ba9ebdb18a61cd4c571 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Mon, 25 May 2026 15:17:05 +0530 Subject: [PATCH] fix: skip AutoAssignment bulk loop when no agents are online (#14500) ## Description When an inbox has `enable_auto_assignment` and `assignment_v2` enabled but no agents are currently online, `AutoAssignment::AssignmentService#perform_bulk_assignment` still loaded up to 100 unassigned conversations and iterated each one, calling `inbox.available_agents` per conversation. Each call hits Redis presence lookups that return empty, no conversations get assigned, and the loop finishes having done only wasted work. For a busy inbox with a long unassigned backlog and offline agents, this is hundreds of Redis ops per job, multiplied by every `AutoAssignment::AssignmentJob` enqueue from the per-save handler. The pressure is significant when inbound volume is high. This adds a single early-return guard: if `inbox.available_agents.empty?`, return `0` immediately. Existing semantics are preserved (jobs are still enqueued on conversation events; they just exit cheaply when there is no one to assign to). ## Type of change - [x] Performance improvement (non-breaking change) ## Test coverage - [x] Added specs --- app/services/auto_assignment/assignment_service.rb | 8 +++++--- .../auto_assignment/assignment_service_spec.rb | 13 +++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/services/auto_assignment/assignment_service.rb b/app/services/auto_assignment/assignment_service.rb index f2d2799ffdf..0ad8a9004ab 100644 --- a/app/services/auto_assignment/assignment_service.rb +++ b/app/services/auto_assignment/assignment_service.rb @@ -5,12 +5,14 @@ class AutoAssignment::AssignmentService return 0 unless inbox.auto_assignment_v2_enabled? return 0 unless inbox.enable_auto_assignment? - assigned_count = 0 + conversations = unassigned_conversations(limit).to_a + return 0 if conversations.empty? + return 0 if inbox.available_agents.empty? - unassigned_conversations(limit).each do |conversation| + assigned_count = 0 + conversations.each do |conversation| assigned_count += 1 if perform_for_conversation(conversation) end - assigned_count end diff --git a/spec/services/auto_assignment/assignment_service_spec.rb b/spec/services/auto_assignment/assignment_service_spec.rb index 36a8c78160b..eb6ebf060ac 100644 --- a/spec/services/auto_assignment/assignment_service_spec.rb +++ b/spec/services/auto_assignment/assignment_service_spec.rb @@ -56,6 +56,19 @@ RSpec.describe AutoAssignment::AssignmentService do expect(conversation.reload.assignee).to be_nil end + it 'short-circuits without iterating conversations when no agents are online' do + 3.times do + conv = create(:conversation, inbox: inbox, status: 'open') + conv.update!(assignee_id: nil) + end + allow(OnlineStatusTracker).to receive(:get_available_users).and_return({}) + + expect(service).not_to receive(:perform_for_conversation) + + assigned_count = service.perform_bulk_assignment(limit: 10) + expect(assigned_count).to eq(0) + end + it 'respects the limit parameter' do 3.times do conv = create(:conversation, inbox: inbox, status: 'open')