You could design this process to run as one loop that gives away all of the "free" points that users have donated. Remove any user that has received > 1 point until all points are assigned. One advantage of this approach is that you could do it all in a single database transaction.
Keep track of the points donated per day some other way, say in Redis or in a database table. Set your worker queue so that there is no concurrency, i.e., number_of_workers=1. On each worker run, give away a point, and note who received it. If number_received(today) > 1 then find someone else.
Anywhere you can avoid concurrency problems, you should.
Also, quick note on #2 and concurrency in general: this is what database transactions are for. Database transactions make sure your rules are consistently enforced, even if the point giveaway happens in real time. Something like:
BEGIN TRANSACTION; SELECT * FROM points_to_assign LIMIT 1 FOR UPDATE; SELECT * FROM assigned_points WHERE day = today() FOR UPDATE; -- grab random user for update, locking that record -- perform update -- make sure that assigned_points for that user is < 2 or ROLLBACK COMMIT;
This is a good candidate for a database stored procedure.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community