YOU WILL REGRET THIS

Preview:

DESCRIPTION

A lightning talk given at the London Erlang Factory in 2011, discussing Erlang anti-patterns seen in real world applications.

Citation preview

YOU WILL REGRET THIS!My Other Mood is 'Even More Angry'

Friday, June 10, 2011

I'M GONNA TELL YOU A STORYIn which I tell you how to behave

- how dare I?

Friday, June 10, 2011

SOCKET.IO-ERLANG

•Developed by Yurii Rashkovskii, Omar Yasin, Fred Hebert (me)

• Used as a base demo app for this presentation

• Allows to write neat front-ends for conversational websites

Friday, June 10, 2011

BIZARRO SOCKET.IO-ERLANG

• 'Bad' socket.io-erlang used for the presentation

• Freely substitutes dependencies and actual code for whatever purpose I have

Friday, June 10, 2011

APP STRUCTURE

Friday, June 10, 2011

APP STRUCTUREBunch of supervisors

Friday, June 10, 2011

APP STRUCTUREBunch of supervisors

web server

Friday, June 10, 2011

APP STRUCTUREBunch of supervisors

web servertransport handlers

Friday, June 10, 2011

APP STRUCTUREBunch of supervisors

web servertransport handlers

Client code attaches here

Friday, June 10, 2011

WE USE A WEB SERVER

•We need a web server (the slide's title says just that (and also the previous slide))

•Oh, Carrying parameters and a connection around is annoying!

• Let's use parametrised modules!

Friday, June 10, 2011

PARAMETRISED MODULES

-­‐module(test_module,  [Param1]).some_method()  -­‐>  Param1.

Equivalent to:

-­‐module(test_non_pmod).some_method(Param1)  -­‐>  Param1.

Friday, June 10, 2011

PARAMETRISED MODULES

1> X = test_module:new(horror), X:some_method().horror

2> test_non_pmod:some_method(sane).sane

Friday, June 10, 2011

PARAMETRISED MODULES

• They are great!

•We can use them as if they were objects!

• They let us carry everything as one large parameter!

• Let's do this!

Friday, June 10, 2011

PARAMETRISED MODULES

• They are great!

•We can use them as if they were objects!

• They let us carry everything as one large parameter!

• Let's do this!

Friday, June 10, 2011

What?

Friday, June 10, 2011

I'LL TELL YOU WHAT

3> dbg:tp({X, some_method, 0}, [...]).** exception error: no case clause matching {test_module,horror}

4> dbg:tp({test_module, some_method, 0}, [...]).* never matches anything *

5> dbg:tp({test_module, some_method, 1}, [...]).* will actually match stuff *

Friday, June 10, 2011

What is this I don't even...

Friday, June 10, 2011

I'LL TELL YOU WHAT

• The parameters are global and they ghost values, become implicit function arguments. Errors out of nowhere.

• They're based on a old fun hack ({Mod, Fun}:(Args))

• They mess up the concept of arity

• They mess up tracing (previous slide!)

• They were added because some library accepts callback modules and nothing else but might still need state around. No other reason.

Friday, June 10, 2011

I'll use them anyway(in my server)

Friday, June 10, 2011

YOU PROBABLY SHOULDN'TBut you might not have a choice, so let's keep going

Friday, June 10, 2011

WHAT ELSE DO WE HAVE?

• A supervision tree, of course!

• Some of the supervisors are tricky and must interact with servers and dynamic children and ...

•Who starts who? By which API?

•We could probably just forget about supervisors, link stuff together and make it simpler

• Let's do this!

Friday, June 10, 2011

IN THIS VERY SLIDE I PRETEND I MAKE THE CHANGES

Friday, June 10, 2011

APP STRUCTURE

Friday, June 10, 2011

APP STRUCTUREtransport handlers

were moved and no longer need a supervisor.

They only use links.

The code is more straightforward!

Friday, June 10, 2011

APP STRUCTUREtransport handlers

were moved and no longer need a supervisor.

They only use links.

The code is more straightforward!

Friday, June 10, 2011

What?... my code is so much easier to read now!

Friday, June 10, 2011

I'LL TELL YOU WHAT

• You need to add ad-hoc start/restart policies and make sure orderly shutdowns work fine with just links. Care to add tests?

• You can no longer benefit from systool's application upgrades and downgrades as they depend on supervisors

• You will need to take your app down!

Friday, June 10, 2011

It's okay, I'll do rolling upgrades through all nodesthis should avoid downtime

Friday, June 10, 2011

NOT WITH LIVE SESSIONS!Nobody likes to be disconnected during a conversation!

Would you disconnect this guy?

Friday, June 10, 2011

NOT WITH LIVE SESSIONS!Nobody likes to be disconnected!

Stolen from Yurii's talk earlier today

Friday, June 10, 2011

NOT WITH LIVE SESSIONS!Nobody likes to be disconnected!

Stolen from Yurii's talk earlier today

Friday, June 10, 2011

You're killing me. I'll leave the change in. Code is meant to be

read first!

Friday, June 10, 2011

OK, AS LONG AS YOU LISTEN TO THE NEXT POINT

Friday, June 10, 2011

SURE, I'M HAPPY WITH MY APP

• It's all done in OTP

•Now Easier to read

• Uses parametrized modules, hell yes!

• It's time to start it!

• Let's do this!

Friday, June 10, 2011

THIS IS GONNA BE FUN

main(_) -> appmon:start(), sasl:start(normal, []), socketio:start(normal,[]), {ok, Pid} = socketio_listener:start([ {http_port, 7878}, {default_http_handler,?MODULE}]), EventMgr = socketio_listener:event_manager(Pid), ok = gen_event:add_handler(EventMgr, ?MODULE,[]), receive _ -> ok end.

And it works!(believe me)

Friday, June 10, 2011

THIS IS GONNA BE FUN

main(_) -> appmon:start(), sasl:start(normal, []), socketio:start(normal,[]), {ok, Pid} = socketio_listener:start([ {http_port, 7878}, {default_http_handler,?MODULE}]), EventMgr = socketio_listener:event_manager(Pid), ok = gen_event:add_handler(EventMgr, ?MODULE,[]), receive _ -> ok end.

And it works!(believe me)

Friday, June 10, 2011

YOU, AGAIN!?You are worse than clippy

What is it this time?

Friday, June 10, 2011

I'LL TELL YOU WHAT

• The VM starts all applications under the Application Controller

• Starting one outside of it means it is not supervised by it

•No app failure strategy (permanent, transient, temporary)

•No access to 'env' variables

•No respect of start phasesor dependencies

Friday, June 10, 2011

AND IT GETS WORSE•With bad default values (or overly defensive code) for env

variables, bad things happen...

• In this case, infinitely many web sockets opened for each client(before a patch to change that, because I forgot to listen to this hint)

Friday, June 10, 2011

DO THIS INSTEAD

main(_) -> appmon:start(), application:start(sasl), application:start(misultin), application:start(socketio), {ok, Pid} = socketio_listener:start([ {http_port, 7878}, {default_http_handler,?MODULE}]), EventMgr = socketio_listener:event_manager(Pid), ok = gen_event:add_handler(EventMgr, ?MODULE,[]), receive _ -> ok end.

And it works better!(believe me)

Friday, June 10, 2011

Oh...

Friday, June 10, 2011

RIGHTYour OTP code is not worth much without that

Friday, June 10, 2011

One more thing...

Friday, June 10, 2011

DON'T LISTEN TO MEIf your product might not ship because of this.Making it work is #1. Making it pretty is not.

Friday, June 10, 2011

HAPPY HACKINGHopefully you won't regret this

Friday, June 10, 2011

Recommended