In an interview, I was asked to design a Scratch Card system like the Google Pay scratch card.
I have come up with a design but is not scalable. Can you suggest a scalable solution?
Requirements:
1. start time and end time -> scratch card should appear after x interval of mins
2. pool of rewards - [{10:1000, 5: 20000, 50:100, Missed: unlimited}] ie, key - amount, value -quantity of rewards available
3. weightage of rewards(probability) - [{10:20, 5:50, 50: 2, Missed: 25}] ie, key -amount, value -weightage
4. 1 user can have 1 reward from a pool within x interval
5. Scratch card availability timings: 10 A.M - 4 P.M and each scratch card is presented after 2 hours
6. in a day 4 scratches person can do, At max, he can actually earn a reward is a number y
Here I am concentrating only on the 'claim' API design. ie, the design for claiming a scratch card.
API:
POST /scratch/
{
"user_id": <user_id>
}
Tables
Format: table_name - column, column...
user - user_id, user_name
screatch_card - scratch_card_id, amount, available_pool, weightage, generated_time, end_time, availability_interval
user_scratch_card_map - user_id, scratch_card_id, scratched_time
Algorithmic Steps(pseudo-code):
- receives a request
POST /scratch/
- Lookup user_scratch_card_map with userid and current day(timestamp)
- If the amount received is greater than allowed, reject the transaction
- If the time is outside the given range, also reject the transaction
- Else:
# get the slot to see if the user availed a scratch card during this time
index = Floor[(current_time - generated_time ) / availability_interval]
if scratched time in between [generated_time + availability_interval: generated_time + index * availability_interval]:
skip this scratch card
# Logic to select a scratch card
total weight -> 87 (sum of all the weights of scratch cards)
index = floor(Math.rand()* total_weight )
selected_scratch_card = List_available_scratch_card[index]
- After selecting the scratch card, update the tables
'user_scratch_card_map', 'screatch_card'
by locking both the tables(a transaction)
The problem lies mostly in step 6. It is hardly extensible. I have to make a lock on screatch_card
means not allowed to other users when one update in progress.
Can you help me to extend this logic to a distributed system so that it is highly available and huge traffic is there?
Aucun commentaire:
Enregistrer un commentaire