I’ve a list of IP addresses (5) that I can connect to from my phoenix web application, what will be the best way to implement a round robin algorithm on the list of IPs, I thought about using a GenServer and maintaining it’s state as the IPs, in that case I’ve a serialised access to the list and can handoff the IPs in a serialised manner. My fear is that the GenServer could a bottleneck to the application when I’ve a lot of requests.
@kodepett This may be interesting for you:
Thanks for the article, I’m well aware of the dangers in using a GenServer as a solution for the above problem. I’m looking for the best solution in this context. I tried using
:erlang.phash2, not sure it’s the right solution either. Thanks.
Can you elaborate on your concerns with phash2?
Incoming request contains a phone number, I ran the function over the phone number and use the result to fetch an IP address from a ETS table. There’s nothing wrong with the function, just looking for something that will give me the IPs in round robin fashion.
You could use the http://erlang.org/doc/man/counters.html counters module to have a counter that each invocation increments.
rem(counter_value, number of ips) gets you the IP address to use. That would be probably the fastest way to guarantee true round robin ordering.
How high is your throughput and how exact does your round robin need to be?
If you just want more or less the same traffic to each IP, the easiest way would be to randomly select one each time. This would, on average, give the same amount of traffic to each IP and not require any coordination between processes.
If you really need true round robin, a GenServer that simply returns the next IP would be able to handle a pretty huge number of requests. It’s true they’d be serialized, but you wouldn’t run into issues until you had some pretty serious traffic on it.
What are you doing once you get an IP? If you’d benefit from having a persistent connection to each IP that you re-use, poolboy could handle giving you the next available connection.
I will be handling between 5-10k transactions per second, I will run a benchmark to ascertain the performance of the GenServer. Persistent connection is discouraged by the service provider and hence I’ve to open connection as and when I receive a request rather than holding on to the connection and waiting for a request to use/re-use it. I’ve had a bit of experience with
poolboy. Thanks a bunch
Thanks @benwilson512, I will take a look and see how best to use it. I will be handling 5-10k connections per second, will benchmark to see how it performs.
The counters module uses CPU atomic instructions, should be way faster than a genserver.
Hi @benwilson512, I perused the counters doc, do you have any implementation example in elixir that I can peruse. Thanks.