fix: pass serialized data in notification.deleted event to avoid Deserialisation (#13061)
https://one.newrelic.com/alerts/issue?account=3437125&duration=259200000&state=d088e9b7-d0ce-3fcf-fda5-145df8b9cb2a ## Description Pass serialized data instead of ActiveRecord object in dispatch_destroy_event to prevent ActiveJob::DeserializationError when the notification is already deleted. This error occurs frequently because RemoveDuplicateNotificationJob deletes notifications, and by the time the async EventDispatcherJob runs, the record no longer exists. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Avoids ActiveJob deserialization failures by sending serialized data for notification deletion and updating the listener accordingly. > > - `Notification#dispatch_destroy_event` now dispatches `NOTIFICATION_DELETED` with serialized `notification_data` (`id`, `user_id`, `account_id`) instead of the AR object > - `ActionCableListener#notification_deleted` reads `notification_data`, finds `User`/`Account`, computes `unread_count`/`count` via `NotificationFinder`, and broadcasts using the user’s pubsub token > - Specs updated to pass `notification_data` and assert payload (including `unread_count`/`count`) > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e2ffbe765b148fdfd2cd2e031c657c36e423c1f5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
This commit is contained in:
committed by
GitHub
parent
a2e348df06
commit
d526cf283d
@@ -14,11 +14,19 @@ class ActionCableListener < BaseListener
|
|||||||
end
|
end
|
||||||
|
|
||||||
def notification_deleted(event)
|
def notification_deleted(event)
|
||||||
return if event.data[:notification].user.blank?
|
notification_data = event.data[:notification_data]
|
||||||
|
|
||||||
notification, account, unread_count, count = extract_notification_and_account(event)
|
user = User.find_by(id: notification_data[:user_id])
|
||||||
tokens = [event.data[:notification].user.pubsub_token]
|
account = Account.find_by(id: notification_data[:account_id])
|
||||||
broadcast(account, tokens, NOTIFICATION_DELETED, { notification: { id: notification.id }, unread_count: unread_count, count: count })
|
return if user.blank? || account.blank?
|
||||||
|
|
||||||
|
notification_finder = NotificationFinder.new(user, account)
|
||||||
|
tokens = [user.pubsub_token]
|
||||||
|
broadcast(account, tokens, NOTIFICATION_DELETED, {
|
||||||
|
notification: { id: notification_data[:id] },
|
||||||
|
unread_count: notification_finder.unread_count,
|
||||||
|
count: notification_finder.count
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_cache_invalidated(event)
|
def account_cache_invalidated(event)
|
||||||
|
|||||||
@@ -180,7 +180,17 @@ class Notification < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_destroy_event
|
def dispatch_destroy_event
|
||||||
Rails.configuration.dispatcher.dispatch(NOTIFICATION_DELETED, Time.zone.now, notification: self)
|
# Pass serialized data instead of ActiveRecord object to avoid DeserializationError
|
||||||
|
# when the async EventDispatcherJob runs after the notification has been deleted
|
||||||
|
Rails.configuration.dispatcher.dispatch(
|
||||||
|
NOTIFICATION_DELETED,
|
||||||
|
Time.zone.now,
|
||||||
|
notification_data: {
|
||||||
|
id: id,
|
||||||
|
user_id: user_id,
|
||||||
|
account_id: account_id
|
||||||
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_last_activity_at
|
def set_last_activity_at
|
||||||
|
|||||||
@@ -132,7 +132,14 @@ describe ActionCableListener do
|
|||||||
describe '#notification_deleted' do
|
describe '#notification_deleted' do
|
||||||
let(:event_name) { :'notification.deleted' }
|
let(:event_name) { :'notification.deleted' }
|
||||||
let!(:notification) { create(:notification, account: account, user: agent) }
|
let!(:notification) { create(:notification, account: account, user: agent) }
|
||||||
let!(:event) { Events::Base.new(event_name, Time.zone.now, notification: notification) }
|
let(:notification_data) do
|
||||||
|
{
|
||||||
|
id: notification.id,
|
||||||
|
user_id: agent.id,
|
||||||
|
account_id: account.id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
let!(:event) { Events::Base.new(event_name, Time.zone.now, notification_data: notification_data) }
|
||||||
|
|
||||||
it 'sends message to account admins, inbox agents' do
|
it 'sends message to account admins, inbox agents' do
|
||||||
expect(ActionCableBroadcastJob).to receive(:perform_later).with(
|
expect(ActionCableBroadcastJob).to receive(:perform_later).with(
|
||||||
|
|||||||
Reference in New Issue
Block a user