Reputation: 1712
I am creating a matchmaking system in my rails application where users can post matches for a certain time. If the time the match is posted for is reached without being accepted I need to void that match by setting its active flag to false.
What would be the best approach for this? I have read bad things about cluttering up models with too many callbacks, and am not sure if ActiveModel Dirty is the best solution here. Does anybody have a suggestion that goes along with best practices and does not require a ton of DB queries?
Upvotes: 0
Views: 47
Reputation: 7231
Here's two ideas that should get you started. For all approaches I suggest encapsulating the business logic for creating a new match in a service object, to avoid the cluttering of the model you already mentioned.
immediately after persisting, store the match' id in Redis using a pre-defined TTL. For example using a key in the form matches:open:1234
. Whenever you need a list of open matches, just query the keys under matches:open:*
and you can use those to do a targeted query on your ActiveRecord DB. Expiration will be completely out of your hair. You can also easily "touch" a record if you want to keep the match open for a bit longer. Just pay attention to your database transactions and the possibility of rollbacks: you don't want to write invalid database ids into Redis :)
when creating the match, also enqueue a job (either via ActiveJob or a more specific framework like Sidekiq) that retrieves the record and checks whether it has been accepted in the meantime. You can optimize this by using something like where(id: match_id, accepted_at: nil).first
and if nil
is being returned, you can assume that the match has been accepted in the meantime without having to instantiate the record. If you need functionality to keep a match open for longer than the initial delay, you'll need to search for and cancel the already-enqueued job and enqueue a new one.
As for periodically querying all pending matches in a recurring job, it makes protection against race conditions a bit harder with regards to row level locks and also is much harder to scale, so I personally would advise against it.
Upvotes: 1