Reputation: 341
I want to create some notifications that should be short-lived, 1 day or so. So that I can send out those notifications if the user is accessing all notifications today, but not tomorrow.
Suppose someone is creating some post with, I want to send them a notification whenever post upload is successful. But that notification won't matter tomorrow and will create unnecessary confusion.
I considered using Sidekiq
for the process, in an after_commit
hook, trigger a sidekiq
job to run after 18 hrs
, something like:
after_commit :trigger_destroyer
private
def trigger_destroyer
if notification_type == 'shortlived'
NotificationDestroyer.perform_in(3.hours.from_now, id)
end
end
Or I can run a cron job that will read created_at, and type of notifications and delete them there.
Is there any better approach?
Upvotes: 0
Views: 91
Reputation: 101811
You could create a ActiveJob or Rake task that purges the entire table instead:
class NotificationCleanupJob < ApplicationJob
queue_as :default
def perform
Notification.where('created_at < ?', 30.days.ago).delete_all
end
end
There are various gems that can be used to set up recurring jobs such aswhenever
,chrono
, clockwork
and rufus-scheduler
. Heroku also has a built in scheduler.
This is far more effective then setting up jobs that do this one row at a time and which will pretty much constantly eat up worker processes.
This should be combined with filtering when you display / use the records in Rails.
Upvotes: 3
Reputation: 11196
This is an elaboration on the previous answer. You probably just want to set up a scope for displaying the notifications to the users, so something like this should work.
class Notification
belongs_to :user
STALE_DAYS ||= (ENV['STALE_NOTIFICATIONS_PERIOD'].to_i || 30).min
scope :active { where('created_at > ?', (STALE_DAYS).days.ago) }
scope :stale { where('created_at <= ?', (STALE_DAYS).days.ago) }
def to_s
self.text # or whatever name of notification body field is
end
end
Run this job ever stale
days.
class NotificationCleanupJob < ApplicationJob
queue_as :default
def perform
Notification.where('created_at < ?', (stale).days.ago).delete_all
end
end
Then in your views you can do something like this:
<% @user.notifications.active.each |notification| %>
<div class="notification">
<%= notification %>
</div>
<% end %>
Upvotes: 0
Reputation: 10898
If you want these notifications displayed when the user visits the site, you don't need to do anything special with Sidekiq, Redis, Cron, etc. All you need to do is load notifications younger than 24 hours and display them.
As an additional task, you could delete any notifications older than 24 hours at the same time, perhaps also deleting notifications you've displayed ... depending on your needs.
However, if these notifications are to be sent directly to the user without them performing an action (loading a page) to trigger the notification, then you'll need to use some kind of scheduling system like Sidekiq.
Upvotes: 1