fix: remove bulk_auto_assignment_job cron schedule (#13877)

This commit is contained in:
Tanmay Deep Sharma
2026-03-31 10:56:59 +05:30
committed by GitHub
parent 0012fa2c35
commit 1987ac3d97
4 changed files with 14 additions and 151 deletions

View File

@@ -1,47 +0,0 @@
class Inboxes::BulkAutoAssignmentJob < ApplicationJob
queue_as :scheduled_jobs
include BillingHelper
def perform
Account.feature_assignment_v2.find_each do |account|
if should_skip_auto_assignment?(account)
Rails.logger.info("Skipping auto assignment for account #{account.id}")
next
end
account.inboxes.where(enable_auto_assignment: true).find_each do |inbox|
process_assignment(inbox)
end
end
end
private
def process_assignment(inbox)
allowed_agent_ids = inbox.member_ids_with_assignment_capacity
if allowed_agent_ids.blank?
Rails.logger.info("No agents available to assign conversation to inbox #{inbox.id}")
return
end
assign_conversations(inbox, allowed_agent_ids)
end
def assign_conversations(inbox, allowed_agent_ids)
unassigned_conversations = inbox.conversations.unassigned.open.limit(Limits::AUTO_ASSIGNMENT_BULK_LIMIT)
unassigned_conversations.find_each do |conversation|
::AutoAssignment::AgentAssignmentService.new(
conversation: conversation,
allowed_agent_ids: allowed_agent_ids
).perform
Rails.logger.info("Assigned conversation #{conversation.id} to agent #{allowed_agent_ids.first}")
end
end
def should_skip_auto_assignment?(account)
return false unless ChatwootApp.chatwoot_cloud?
default_plan?(account)
end
end

View File

@@ -34,7 +34,18 @@ end
# https://github.com/ondrejbartas/sidekiq-cron
Rails.application.reloader.to_prepare do
# TODO: Switch to `load_from_hash!(..., source: 'schedule')` once we have a
# safe cleanup path for YAML-backed cron jobs already persisted in Redis.
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file) if File.exist?(schedule_file) && Sidekiq.server?
# load_from_hash! upserts jobs from the YAML and removes any Redis-persisted
# jobs that share the same source tag but are no longer in the file.
# This ensures deleted schedule entries are cleaned up on deploy.
if File.exist?(schedule_file) && Sidekiq.server?
schedule = YAML.load_file(schedule_file)
# Cron entries removed from schedule.yml but possibly still in Redis
# with source:'dynamic' (predating the source tag). load_from_hash!
# only cleans up source:'schedule' entries, so these need explicit removal.
# Remove names from this list once they've been through a deploy cycle.
%w[bulk_auto_assignment_job].each { |name| Sidekiq::Cron::Job.destroy(name) }
Sidekiq::Cron::Job.load_from_hash!(schedule, source: 'schedule')
end
end

View File

@@ -4,7 +4,6 @@
# executed daily at 0000 UTC
# schedules daily deferred jobs at stable times for each installation
# keep the existing schedule key while the cron loader still uses load_from_hash
internal_check_new_versions_job:
cron: '0 0 * * *'
class: 'Internal::TriggerDailyScheduledItemsJob'
@@ -50,13 +49,6 @@ delete_accounts_job:
class: 'Internal::DeleteAccountsJob'
queue: scheduled_jobs
# executed every 15 minutes
# to assign unassigned conversations for all inboxes
bulk_auto_assignment_job:
cron: '*/15 * * * *'
class: 'Inboxes::BulkAutoAssignmentJob'
queue: scheduled_jobs
# executed every 30 minutes for assignment_v2
periodic_assignment_job:
cron: '*/30 * * * *'

View File

@@ -1,93 +0,0 @@
require 'rails_helper'
RSpec.describe Inboxes::BulkAutoAssignmentJob do
let(:account) { create(:account, custom_attributes: { 'plan_name' => 'Startups' }) }
let(:agent) { create(:user, account: account, role: :agent, auto_offline: false) }
let(:inbox) { create(:inbox, account: account) }
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: nil, status: :open) }
let(:assignment_service) { double }
describe '#perform' do
before do
allow(assignment_service).to receive(:perform)
end
context 'when inbox has inbox members' do
before do
create(:inbox_member, user: agent, inbox: inbox)
account.enable_features!('assignment_v2')
inbox.update!(enable_auto_assignment: true)
end
it 'assigns unassigned conversations in enabled inboxes' do
allow(AutoAssignment::AgentAssignmentService).to receive(:new).with(
conversation: conversation,
allowed_agent_ids: [agent.id]
).and_return(assignment_service)
described_class.perform_now
expect(AutoAssignment::AgentAssignmentService).to have_received(:new).with(
conversation: conversation,
allowed_agent_ids: [agent.id]
)
end
it 'skips inboxes with auto assignment disabled' do
inbox.update!(enable_auto_assignment: false)
allow(AutoAssignment::AgentAssignmentService).to receive(:new)
described_class.perform_now
expect(AutoAssignment::AgentAssignmentService).not_to have_received(:new).with(
conversation: conversation,
allowed_agent_ids: [agent.id]
)
end
context 'when account is on default plan in chatwoot cloud' do
before do
account.update!(custom_attributes: {})
InstallationConfig.create(name: 'CHATWOOT_CLOUD_PLANS', value: [{ 'name' => 'default' }])
allow(ChatwootApp).to receive(:chatwoot_cloud?).and_return(true)
end
it 'skips auto assignment' do
allow(Rails.logger).to receive(:info)
expect(Rails.logger).to receive(:info).with("Skipping auto assignment for account #{account.id}")
allow(AutoAssignment::AgentAssignmentService).to receive(:new)
expect(AutoAssignment::AgentAssignmentService).not_to receive(:new)
described_class.perform_now
end
end
end
context 'when inbox has no members' do
before do
account.enable_features!('assignment_v2')
inbox.update!(enable_auto_assignment: true)
end
it 'does not assign conversations' do
allow(Rails.logger).to receive(:info)
expect(Rails.logger).to receive(:info).with("No agents available to assign conversation to inbox #{inbox.id}")
described_class.perform_now
end
end
context 'when assignment_v2 feature is disabled' do
before do
account.disable_features!('assignment_v2')
end
it 'skips auto assignment' do
allow(AutoAssignment::AgentAssignmentService).to receive(:new)
expect(AutoAssignment::AgentAssignmentService).not_to receive(:new)
described_class.perform_now
end
end
end
end