Friday, September 28, 2012

Foreman and multiple ports per process

The problem

Composing an application of multiple software components is the de facto standard these days. It's rarely the case for the application to embed a database server, queue server or the like. To help manage the ever growing complexity of this kind of systems we can use Foreman - a Ruby application using a Procfile to spin off instances of declared services (same as for example Heroku uses to manage processes).

Many software components these days besides providing the core functionality tend to give the user some sort of administration interface. That interface is often available under different a port. Up until now Foreman assigned only one single port per process, via the $PORT environment variable. As I started using Foreman recently this inconvenience became a stopper for me trying to start ActiveMQ, 2 instances of MongoDB in a shard and Neo4j with my Sinatra application. All was nice but the lack of ability to start MongoDB's control interface on separate ports blew it all out of the water.

The solution

I've came to the conclusion that it'd be a really handy to use multiple ports not just for the case I just described. And so I created a ticket on GitHub for this. Being a forthcoming guy and all I decided to take a crack at implementing this functionality myself. A few hours later a working and tested solution covering all the cases was ready to be pulled in. Let's see if the maintainer will agree to pull it in :)

How to use it?

Assuming David will pull it in the formula is as follows:
alpha: command_to_start -p1 $PORT -p2 $PORT0
beta:  command_to_start -p1 $PORT1 -p3 $PORT9
What would that mean?

alpha would get assigned 2 ports: $PORT = 50xx and $PORT0 = 51xx
beta would get assigned 3 ports: $PORT = 52xx, $PORT1 = 53xx and $PORT9 = 54xx

Since Foreman makes an assumption that at most 100 ports are assigned to one variable this new functionality uses that to assign ranges for subsequent ports. And because I wanted to stay compatible with results not using this new feature the original port range numeration regardless of the usage of $PORT in the command stayed the same. That's why beta still gets the $PORT assigned even though it is not used.

Have a nice day!

No comments: