You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All of the above works as is, but it produces a notifications table that never shrinks.
Use case for deleting
There's a classification of applications where notifications are important until they're read, in which case it's ok to delete the notification.
I was able to modify my app/models/notification.rb class with:
defself.mark_as_read!delete_allend
This deletes instead of updates which partially allows the use case of wanting to delete read notifications instead of marking them as read with a timestamp.
The problem now is you'll get this error when Noticed tries to deserialize a notification that doesn't exist when it tries to deliver an email:
ActiveJob::DeserializationError: Error while trying to deserialize arguments: Couldn't find Notification with 'id'=54
What I tried so far
Enabling discard_on ActiveJob::DeserializationError in app/jobs/application_job.rb does discard the job but the job is already set in motion and the job will continue to be retried and continue to be discarded until ActiveJob gives up. This creates a lot of busy work for your job processor (such as Sidekiq).
I also tried adding this condition to my email deliver_by recipient.email? && Notification.exists?(record.id) but this didn't prevent Noticed from trying to deserialize the notification. As a side note this also produces (2) queries that look up the notification. The first is when Noticed deserializes and the 2nd is the exists? query. I tried changing that to .find which produced an identical query as Noticed's query but Rails didn't cache it.
I'd like to avoid using using begin / rescue since using that for control flow feels a little dirty and can be inefficient.
Best case scenario
1 DB query is performed by this gem to see if it can deserialize the notification. If it cannot (it returned nil) then the job would get deleted or whatever action makes sense to say "This job is dead, don't retry".
No exceptions would be thrown or need to be rescued.
Is there a way to make the above happen when both updating or deleting in a way that all users would be happy? I could see not wanting a silent no-op for certain apps so maybe an option needs to exist to handle this?
Is there another way to handle this use case? Maybe even without a gem patch?
This discussion was converted from issue #293 on October 31, 2023 19:37.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi,
Problem statement
Your
notifications
table can get pretty big in size over time since it's ever growing.Currently when you mark a notification as read, the record's
read_at
time gets updated with this code snippet fromlib/noticed/model.rb
:Within your notifications you may want to only deliver emails if a record is unread. The docs cover this use case:
All of the above works as is, but it produces a
notifications
table that never shrinks.Use case for deleting
There's a classification of applications where notifications are important until they're read, in which case it's ok to delete the notification.
I was able to modify my
app/models/notification.rb
class with:This deletes instead of updates which partially allows the use case of wanting to delete read notifications instead of marking them as read with a timestamp.
The problem now is you'll get this error when Noticed tries to deserialize a notification that doesn't exist when it tries to deliver an email:
What I tried so far
Enabling
discard_on ActiveJob::DeserializationError
inapp/jobs/application_job.rb
does discard the job but the job is already set in motion and the job will continue to be retried and continue to be discarded until ActiveJob gives up. This creates a lot of busy work for your job processor (such as Sidekiq).I also tried adding this condition to my email deliver_by
recipient.email? && Notification.exists?(record.id)
but this didn't prevent Noticed from trying to deserialize the notification. As a side note this also produces (2) queries that look up the notification. The first is when Noticed deserializes and the 2nd is theexists?
query. I tried changing that to.find
which produced an identical query as Noticed's query but Rails didn't cache it.I'd like to avoid using using begin / rescue since using that for control flow feels a little dirty and can be inefficient.
Best case scenario
Is there a way to make the above happen when both updating or deleting in a way that all users would be happy? I could see not wanting a silent no-op for certain apps so maybe an option needs to exist to handle this?
Is there another way to handle this use case? Maybe even without a gem patch?
Beta Was this translation helpful? Give feedback.
All reactions