Server instance per request

The thing that attracted me to elixir was the erlang infrastructure underneath it. As I’ve learned more, and used more of it, the simplicity continues to fire my imagination. I hadn’t quite got as far as pushing the boat out this far, but it’s a fascinating idea:

Similar (in its spin-up-on-demand aspect) to AWS Lambda?

What is the advantage? It seems like ‘the opposite of caching’. I see the advantage of starting processes fast if there is unusual demand but not of tearing them down and the energy of deleting data.

AWS Lambda looks closer to a regular task manager (with AWS sauce, presumably). i.e. Similar to sidekick or resque in rubyland. They operate similarly, where you enqueue tasks that have implemented perform() i.e. use perform() as the lambda.

The idea here, as I vaguely understand it, is being able to spin up services on demand with a trivial amount of delay. There seems to immediately be a couple of benefits: traditional server/vms don’t need to run 24/7, only on demand, which presumably will make them much cheaper; resources required in data centres drop.

When you drop this type of service into the overall elixir/erlang architecture, it’s… interesting.

Perhaps the reason is security. With PHP, for example, each request runs as the same Linux/Unix user, with the same access to the database. a flaw in the PHP code would expose other user’s data (as is the case with SQL injection). NodeJS apps have the same problem, if not worse, since multiple users run in the same process. The Heartbleed flaw showed that information could leak from user to another in other parts of the stack.

For defence in depth, I could see wanting each authenticated user or even each request to sandboxed from each other. To do this properly, it would need user authentication pushed back to the database/API.

Requests in Phoenix (elixir web framework) already run in separate (erlang vm) processes – a request creates a process and sending the response kills it – so access is already limited. The db also runs as a separate (erlang) process within the supervision tree, either within the application’s supervision tree or outside, so it’s only available if you have its pid. There’s nothing to stop programmer error, of course (e.g. get_user_id(:user_id + 1) or similar in a query) but from my experience, you’d have to work quite hard to cross the boundary.

Authentication per request if easy enough with token passing. Phoenix provides Phoenix.Token to make this easier. I presume these dynamic instances would make themselves know to a supervision tree and token verification would be provided by some service. Dunno. Like I said, it’s a fascinating idea. I’m interested to see where folk take it.

This talk by Saša Jurić, Discovering Processes is a good high level view of elixir/erlang process discovery and management. (He’s the author of Elixir in Action.)

Proudly sponsored by Bytemark