fix(captain-memory): isolate per-account failures in SilenceDetectorJob + fix typo
This commit is contained in:
parent
833e76856e
commit
fb6673664a
@ -5,15 +5,26 @@ class Captain::ContactMemories::SilenceDetectorJob < ApplicationJob
|
|||||||
|
|
||||||
def perform
|
def perform
|
||||||
Account.where("custom_attributes->>'captain_contact_memory_extraction_enabled' = 'true'").find_each do |account|
|
Account.where("custom_attributes->>'captain_contact_memory_extraction_enabled' = 'true'").find_each do |account|
|
||||||
elegible_conversation_ids(account).each do |conv_id|
|
process_account(account)
|
||||||
Captain::ContactMemories::ExtractFromConversationJob.perform_later(conv_id)
|
rescue StandardError => e
|
||||||
end
|
Rails.logger.error("[SilenceDetectorJob] account=#{account.id} failed: #{e.class}: #{e.message}")
|
||||||
|
ChatwootExceptionTracker.new(e, account: account).capture_exception
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def elegible_conversation_ids(account)
|
def process_account(account)
|
||||||
|
eligible_conversation_ids(account).each do |conv_id|
|
||||||
|
Captain::ContactMemories::ExtractFromConversationJob.perform_later(conv_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Intentionally no `.where('messages.created_at < ?', SILENCE_THRESHOLD.ago)` pre-filter here:
|
||||||
|
# that would let a conversation with ANY old message + a recent one be incorrectly
|
||||||
|
# classified as silent. The HAVING MAX(...) clause alone is the correct semantics.
|
||||||
|
# If this full-join becomes a perf issue at scale, rewrite as NOT EXISTS subquery.
|
||||||
|
def eligible_conversation_ids(account)
|
||||||
Conversation
|
Conversation
|
||||||
.where(account_id: account.id)
|
.where(account_id: account.id)
|
||||||
.joins(:messages)
|
.joins(:messages)
|
||||||
|
|||||||
@ -49,4 +49,27 @@ RSpec.describe Captain::ContactMemories::SilenceDetectorJob do
|
|||||||
expect { described_class.perform_now }
|
expect { described_class.perform_now }
|
||||||
.not_to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob)
|
.not_to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'continues processing other accounts when one account raises' do
|
||||||
|
bad_account = create(:account, custom_attributes: { 'captain_contact_memory_extraction_enabled' => true })
|
||||||
|
bad_contact = create(:contact, account: bad_account)
|
||||||
|
create(:conversation, account: bad_account, contact: bad_contact)
|
||||||
|
|
||||||
|
good_account = create(:account, custom_attributes: { 'captain_contact_memory_extraction_enabled' => true })
|
||||||
|
good_contact = create(:contact, account: good_account)
|
||||||
|
good_conv = create(:conversation, account: good_account, contact: good_contact)
|
||||||
|
create(:message, conversation: good_conv, account: good_account)
|
||||||
|
age_all_messages(good_conv, 35.minutes.ago)
|
||||||
|
|
||||||
|
original = described_class.instance_method(:eligible_conversation_ids)
|
||||||
|
allow_any_instance_of(described_class).to receive(:eligible_conversation_ids) do |instance, acc| # rubocop:disable RSpec/AnyInstance
|
||||||
|
raise StandardError, 'boom' if acc.id == bad_account.id
|
||||||
|
|
||||||
|
original.bind_call(instance, acc)
|
||||||
|
end
|
||||||
|
allow(ChatwootExceptionTracker).to receive(:new).and_return(instance_double(ChatwootExceptionTracker, capture_exception: true))
|
||||||
|
|
||||||
|
expect { described_class.perform_now }
|
||||||
|
.to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob).with(good_conv.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user