Proportional dispatching using Ruby

In this article we’re going to show you how to implement an algorithm to handle quota-based dispatching using pure Ruby

Tech - RubyCademy
RubyCademy
Published in
3 min readSep 4, 2020

--

In this article we’re going to explore the following topics:

  • use case
  • algorithm
  • implementation in Ruby

Use Case

Our project is an online calendar for professionals. Few weeks ago our clients requested a new feature. They want their client to receive an appointment reminder by SMS.

After negotiating with a set of SMS providers, we decided to give:

  • 70% of our traffic to Provider A
  • 20% of our traffic to Provider B
  • 10% of our traffic to Provider C

Now let’s see how to implement this strategy in our code.

Our Algorithm

Our algorithm requires 3 pieces of information:

  • The rates of all the providers
  • The current volumes of all the providers
  • The total volume

With these 3 information we’re going to be able to determine which provider must send the next SMS using this formula:

Where T = total volume, P = provider volume, S = provider’s processing rate.

So for each rate and volume associated with a provider, we are going to apply the above formula.

Then we select the provider with the biggest result (quota) to process the SMS.

Also, we must apply a set of rules to handle edge cases:

  • when T = 0 then we assign the processing of the SMS to the provider with the biggest rate: provider A in our case (arbitrary rule).
  • if one or more providers have zero volume then assign the processing of the SMS to the provider with zero volume and with the biggest rate.

Now let’s detail the processing of 10 SMS round-by-round in order to understand how it works

Now let’s implement a version of this algorithm in pure Ruby

Quota::Calculator

Before starting, let’s keep in mind that this code doesn’t handle concurrency.

Then let’s run our Quota::DummyDispatcher

irb> Quota::DummyDispatcher.new.dispatch
=> { :a => 700, :b => 200, :c => 100 }

Here we can see that our Quota::DummyDispatcher proportionally dispatches the SMS to send according to the rates defined by our dummy class: a => 70%, b => 20%, c => 10%.

Now let’s detail the content of our implementation. Here, we’ve 2 files:

  • quota/calculator.rb: a module in charge of calculating and comparing the quotas of all the providers. This module also implements the edge cases rules defined earlier.
  • quota/dummy_dispatcher.rb: a test class that simulates 1000 SMS sendings. Then we update the volumes and total volume after each SMS sending.

The Quota::Calculator is pretty simple:

1- We iterate through each rate and if the provider has a volume of zero then we choose the provider with the highest rate among the providers with no volume.

2- When each provider has at least a volume of one we calculate the quota for each provider and we select the provider with the highest quota.

Ruby Mastery

We’re currently finalizing our first online course: Ruby Mastery.

Join the list for an exclusive release alert! 🔔

🔗 Ruby Mastery by RubyCademy

Also, you can follow us on x.com as we’re very active on this platform. Indeed, we post elaborate code examples every day.

💚

--

--