feat(captain-memory): add AgingJob with TTL + LRU cap, weekly cron
This commit is contained in:
parent
fb6673664a
commit
b3077b2b26
@ -107,3 +107,9 @@ captain_contact_memory_silence_detector_job:
|
|||||||
cron: '*/10 * * * *'
|
cron: '*/10 * * * *'
|
||||||
class: 'Captain::ContactMemories::SilenceDetectorJob'
|
class: 'Captain::ContactMemories::SilenceDetectorJob'
|
||||||
queue: scheduled_jobs
|
queue: scheduled_jobs
|
||||||
|
|
||||||
|
# weekly - Sundays at 03:00 UTC - TTL aging + LRU cap of contact memories
|
||||||
|
captain_contact_memory_aging_job:
|
||||||
|
cron: '0 3 * * 0'
|
||||||
|
class: 'Captain::ContactMemories::AgingJob'
|
||||||
|
queue: scheduled_jobs
|
||||||
|
|||||||
47
enterprise/app/jobs/captain/contact_memories/aging_job.rb
Normal file
47
enterprise/app/jobs/captain/contact_memories/aging_job.rb
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
class Captain::ContactMemories::AgingJob < ApplicationJob
|
||||||
|
queue_as :scheduled_jobs
|
||||||
|
|
||||||
|
DELETE_ON_EXPIRE = %w[reclamacao feedback_positivo vinculo_social].freeze
|
||||||
|
MAX_ACTIVE_PER_CONTACT = 50
|
||||||
|
|
||||||
|
def perform
|
||||||
|
soft_delete_expired_deletable
|
||||||
|
prune_per_contact_lru
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def soft_delete_expired_deletable
|
||||||
|
Captain::ContactMemory
|
||||||
|
.where(memory_type: DELETE_ON_EXPIRE)
|
||||||
|
.where('expires_at < ?', Time.current)
|
||||||
|
.where(deleted_at: nil)
|
||||||
|
.update_all(deleted_at: Time.current, updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
|
||||||
|
end
|
||||||
|
|
||||||
|
def prune_per_contact_lru
|
||||||
|
over_limit_contact_ids.each do |contact_id|
|
||||||
|
excess = Captain::ContactMemory.active.for_contact(contact_id).count - MAX_ACTIVE_PER_CONTACT
|
||||||
|
next if excess <= 0
|
||||||
|
|
||||||
|
ids_to_delete = Captain::ContactMemory
|
||||||
|
.active
|
||||||
|
.for_contact(contact_id)
|
||||||
|
.order(last_verified_at: :asc)
|
||||||
|
.limit(excess)
|
||||||
|
.pluck(:id)
|
||||||
|
|
||||||
|
Captain::ContactMemory
|
||||||
|
.where(id: ids_to_delete)
|
||||||
|
.update_all(deleted_at: Time.current, updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def over_limit_contact_ids
|
||||||
|
Captain::ContactMemory
|
||||||
|
.active
|
||||||
|
.group(:contact_id)
|
||||||
|
.having('COUNT(*) > ?', MAX_ACTIVE_PER_CONTACT)
|
||||||
|
.pluck(:contact_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Captain::ContactMemories::AgingJob do
|
||||||
|
let(:account) { create(:account) }
|
||||||
|
let(:contact) { create(:contact, account: account) }
|
||||||
|
|
||||||
|
it 'soft-deletes expired reclamacao (delete on expire type)' do
|
||||||
|
mem = create(:captain_contact_memory, account: account, contact: contact, memory_type: 'reclamacao', expires_at: 1.day.ago)
|
||||||
|
described_class.perform_now
|
||||||
|
expect(mem.reload.deleted_at).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does NOT soft-delete expired preferencia (reduce-weight type)' do
|
||||||
|
mem = create(:captain_contact_memory, account: account, contact: contact, memory_type: 'preferencia', expires_at: 1.day.ago)
|
||||||
|
described_class.perform_now
|
||||||
|
expect(mem.reload.deleted_at).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'applies LRU soft-delete when contact exceeds 50 active facts' do
|
||||||
|
55.times do |i|
|
||||||
|
create(:captain_contact_memory, account: account, contact: contact, last_verified_at: i.days.ago)
|
||||||
|
end
|
||||||
|
described_class.perform_now
|
||||||
|
expect(Captain::ContactMemory.where(contact: contact).active.count).to eq(50)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user