I have a spring boot application for a notification system. Consider sms notifications for which I have n vendors to select from. Every vendor has been promised a certain percentage of our business, say their weightage.
During a time duration say 24 hours, a particular vendor is selected based on their weightage percentage. Due to some reason if a vendor's services are down, our system selects the next highest priority vendor for delivering the notification or if a particular sms is to be sent by a particular vendor only then that is chosen.
Currently I am generating a random number between 0 to 100 and then using its value for selecting a vendor. What I want it to do is to use last window of sms notifications and then balance the percentage of sms sent in the current time window.
Example :
Vendor 1: 20% W, Vendor 2: 30% W and Vendor 3: 50% W.
In first 24 hours I send 10 sms.
- Vendor 1 sent 3 sms -> 30%
- Vendor 2 sent 4 sms -> 40%
- Vendor 3 sent 3 sms -> 30%
So what I would like is if I send 20 sms by the end next time window Then
- Vendor 1 should have sent 3 sms -> 15%
- Vendor 2 should have sent 5 sms -> 25%
- Vendor 3 should have sent 12 sms -> 60%
Averaging over 30 sms for 2 time windows, vendor 1: 20%, vendor 2: 30% and vendor 3: 50%
The same balancing/averaging is to be done over all time windows.
My issue is how to implement this when I don't know the number of sms I will send in a day. The range is generally around a hundred thousands, but sometimes much more.
My current implementation:
if (Objects.nonNull(templateEntity.getSmsVendor())) {
// case 1 - when vendor is specified in notification template, use that vendor
smsNotifier.get(templateEntity.getSmsVendor()).send(notificationRequestDTO);
} else {
// case 2 - when vendor is NOT specified in notification template. Choose weightage wise vendor
int totalProbability = 0;
for (SmsNotifier notifier : smsNotifierList) {
totalProbability += notifier.getWeightage();
}
int randomNumber = RandomUtils.nextInt(0, totalProbability);
int currentProbability = 0;
// vendor1 = 60, vendor2 = 40, Mock = 0
for (SmsNotifier notifier : smsNotifierList) {
if (randomNumber >= currentProbability && randomNumber < currentProbability + notifier.getWeightage()) {
log.error("Selected vendor for sms {} is {} weightage {} current probability {}", notificationRequestDTO, notifier.getId(), notifier.getWeightage(), currentProbability);
notifier.send(notificationRequestDTO);
break;
}
currentProbability += notifier.getWeightage();
}
}
Aucun commentaire:
Enregistrer un commentaire