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
This commit is contained in:
Vishnu Narayanan 2026-05-25 15:17:05 +05:30 committed by GitHub
parent 52da165cb7
commit 6fbff026eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 3 deletions

View File

@ -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

View File

@ -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')