Advanced Usage Recipes

Load Balancer & Circuit Breaker

General case

The following example shows how a request can be made using a load balancer and circuit breaker with a static list of hosts:

>>> from ahoyhoy.utils import Host
>>> host1, host2, host3 = Host('badhost2.bla', 80), Host('google.com', 80), Host('badhost3.bla', 80)
>>>
>>> from ahoyhoy.lb.providers import ListProvider
>>> provider = ListProvider(host1, host2, host3)
>>>
>>> from ahoyhoy.lb import RoundRobinLB
>>> rrlb = RoundRobinLB(provider)
>>>
>>> from ahoyhoy.client import LBClientBuilder
>>> client = LBClientBuilder().add_lb(rrlb).build()
>>> client.get('/')
<Response [200]>
>>> client.get('/')
<Response [200]>
>>> client.get('/')
<Response [200]>

Let’s walk through this example step by step.

>>> from ahoyhoy.utils import Host
>>> host1, host2, host3 = Host('badhost2.bla', 80), Host('google.com', 80), Host('badhost3.bla', 80)

All hosts passed to the load balancer should be Host named tuples containing address and port fields. The default protocol (http or https) will be calculated automatically by the service discovery adapter's method.

>>> from ahoyhoy.lb.providers import ListProvider
>>> provider = ListProvider(host1, host2, host3)

Provider is an interface for providing list of hosts to the load balancer. Custom providers should be derived from the IProvider class.

In this example we use ListProvider. It simply returns the list of hosts from before.

Now we create the load balancer instance and give it the provider. We use a round robin algorithm for this example.

>>> from ahoyhoy.lb import RoundRobinLB
>>> rrlb = RoundRobinLB(provider)

And finally we create a client, using our load balancer.

>>> from ahoyhoy.client import LBClientBuilder
>>> client = LBClientBuilder().add_lb(rrlb).build()
>>> client.get('/')
<Response [200]>
>>> client.get('/')
<Response [200]>
>>> client.get('/')
<Response [200]>

Client has built-in circuit breaker algorithm, so if there’s a bad host, it’ll be marked as unavailable and won’t be used for further requests.

Another load balancer example

Here’s another load balancer example, using the random algorithm:

>>> from ahoyhoy.utils import Host
>>> host1, host2 = Host('badhost2.bla', 80), Host('google.com', 80)
>>> from ahoyhoy.lb.providers import ListProvider
>>> provider = ListProvider(host1, host2)
>>> from ahoyhoy.lb import RandomLB
>>> rrlb = RandomLB(provider)
>>> from ahoyhoy.client import LBClientBuilder
>>> client = LBClientBuilder().add_lb(rrlb).build()
>>> client.get('/')
<Response [200]>

Custom Retries

By default a LBClientBuilder‘s load balancer uses a ahoyhoy.retries.Retry() object set to do 3 tries.

Custom Retry objects may be passed to LBClientBuilder like so:

>>> from requests.exceptions import ConnectTimeout
>>> from ahoyhoy.retries import Retry
>>> retry = Retry(exceptions=ConnectTimeout, tries=2, delay=0, max_delay=None, backoff=2, jitter=1)
>>> client = LBClientBuilder().add_lb(rrlb).add_retries(retry).build()
>>> client.get('/')
<Response [200]>

Setting the protocol (http or https)

Http is used by default. To use Https, simply make sure that your Host uses port 443.

>>> host1 = Host('api.service.com', 443)