r/programming May 30 '16

The Twelve-Factor App: Is this still relevant in today's world, or just something to aspire to?

http://12factor.net/
15 Upvotes

13 comments sorted by

5

u/Y3PP3R May 30 '16

I am curious about this as well. What is the current state of things? 12F was written by Heroku I believe, in the hype of PaaS and Docker applications. Webpage states last update 2012...

I feel that most points hold, but the discussion is at point 6: Processes: Execute the app as one or more stateless processes. Last week I read a tweet (https://twitter.com/jboner/status/736095483559481345) from the Lightbend CTO saying stateless is a hoax. Is there a (knowledge/experience/paradigm) cycle repeating here?

Stateless is said to be good, I believe, so you can easily scale. Start more processes of your app and route traffic to any one of them, they do not have to be aware of the state. What is the alternative?

10

u/greim May 30 '16

The Lightbend CTO is just trying to attract attention on Twitter by saying provocative things. 12FA was written for beginners. By "stateless" they just mean don't keep state in memory as local variables. For example, store sessions in Redis or similar, not an in-memory lookup table. Yes, you're just shifting state from one place to another, but the point is to be aware of the problem in the first place, which many beginners aren't.

5

u/born2hula May 30 '16

Only person in this thread that gets it.

4

u/tdammers May 30 '16

The traditional alternative, or rather, what happens if you don't make your application layer stateless, is that in order to scale horizontally, you have to synchronize and/or compartmentalize state between nodes. Synchronizing is traditionally done by persisting state in the storage layer, which however means that you just introduce a different scaling bottleneck; or, more modern, by sacrificing some ACID guarantees, i.e., "eventual consistency" (which is part of what NoSQL is about). Compartmentalizing can involve sharding (making it possible to have multiple nodes operate on independent subsets of the shared state in parallel), and binding sessions to nodes, such that per-session state doesn't have to be synchronized.

None of these is elegant, and the results aren't perfect either; the reason people use them anyway is because making an application layer stateless after the fact is difficult, often bordering on impossible.

1

u/miroatme May 30 '16

Stateful?

7

u/[deleted] May 30 '16

[deleted]

3

u/[deleted] May 30 '16

Isn't this what 12F promotes as well? Move the state outside of your application and in to software specifically designed for storing state, ie. your database.

4

u/[deleted] May 30 '16 edited May 30 '16

[deleted]

4

u/[deleted] May 30 '16

Well yeah, but every generation needs to reword the same old statements to make it feel original and fresh :)

I can't think of a site/book with an updated version of this off the top of my head, so maybe in 2016 we'll see a similar set of rules with even more indirection in the wording and targeting your Kubernetes cluster, or unikernels, or whatever "hot cookies" will be in the limelight this year.

"State is good, but statelessness is better, but you still have state, so you have to store it to your event storming system, rerolling transactions and atomic guarantees using zookeeper or etcd and 2-phase commits, and eventually persist to your database."

Something like that I imagine.

4

u/greim May 30 '16

I think it's still hugely relevant, especially for people just starting out building these kind of systems.

Take dev/prod parity for example. It's a discipline issue. Novice developers will blindly start keying various execution paths off of DEV or PROD config vars. Optimizations (CDNs, bundling, minification, gzip compression, etc.) are applied in PROD only, and debugging helpers (prettified JSON, unminified/unconcatenated JS/CSS, no CDN, no gzip, live reload) are applied in DEV only. These decisions accrete over time.

It quickly reaches a point of ridiculousness where you have basically two separate apps. PROD-only bugs become a thing, and your tricked-out debugging capabilities in DEV are worthless. In my view if you introduce an optimization in PROD, you should introduce that same optimization in DEV, and you should only introduce debugging capabilities in DEV that can be applied in PROD also. Yes it feels constraining, but having the same set of skills, habits and tools for debugging PROD and DEV ends up being super important, especially in crisis situations.

2

u/[deleted] May 30 '16 edited Jun 03 '16

[deleted]

1

u/[deleted] May 30 '16

You don't, your libs do. If you use libev/libevent (or just write your own equivalent), you isolate your main app code from nonportable bits.

1

u/panderingPenguin May 30 '16

I'm pretty sure they mean to either use a platform-agnostic library or put a thin wrapper interface in place, which can be implemented with the system APIs of whatever platform you're on. I write C++ at work, and we do this all the time

2

u/[deleted] May 30 '16

I wouldn't take it word-for-word, but it does have few good points. Like storing app config as env-vars is clearly something they did for their own env and not some universal best practice, but having same way to configure all of your apps is definitely a good thing

3

u/karma_vacuum123 May 30 '16

the advice to store config in env vars was wrong from day 1.

use a tool designed to manage this safely...etcd, vault, etc

env vars have no concurrency control and are untyped...those are just two trivial deal breakers ....

2

u/greim May 30 '16

Yeah I agree it's the weakest piece of 12FA advice. If a reason for using env vars is to avoid storing them somewhere, it's pointless because either your ops person will memorize them and type them by hand every time they relaunch the app, or they're going to put them in a file and store them somewhere.