Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Why Erlang?

Why Erlang?

With web applications today there is an increasing need for systems that can scale up easily and tolerate the network, hardware, and software errors that occur at scale. Building such systems is challenging, if not impossible, to do in many popular programming languages today. Erlang was designed for telephony systems where uptime requirements were law, and as such was designed to solve these challenges. In this talk I will show how Erlang can be used to solve some of the most challenging problems software developers face today. I will introduce concurrency constructs that Erlang provides and show how they can be used to build reliable and scalable applications. This talk will focus mostly on the new concepts introduced by Erlang, but I will also do a few demos and show code samples to illustrate some of the concepts.

Trevor Brown

July 20, 2017
Tweet

More Decks by Trevor Brown

Other Decks in Programming

Transcript

  1. Reliability “the quality of being trustworthy or of performing consistently

    well.” – Google Dictionary • Characteristic of good server software • Something that must be addressed during development
  2. Potential Faults - Hardware • Hardware faults will be encountered

    • Transient faults – Loss of power – Loss of network connectivity – Disk full • Permanent faults – Hard disk failure • Human error
  3. Potential Faults - Software • Again, software faults will be

    encountered • Unanticipated hardware failures • Software bugs present in other systems • Software bugs in your own code
  4. Fault Tolerance • Reliable software must be able to handle

    faults in an intelligent way – Sometimes crashing – Sometimes retrying the failed action – Ignoring faults is always bad • Without some sort of fault tolerance larger software systems will be brittle, crashing the first time a fault occurs
  5. Most Languages • Weren’t designed with fault tolerance in mind

    • Don’t have constructs for dealing with unexpected exceptions • Not suited for long-running server software • Usually rely on other OS-level tools when faults crash the application
  6. Data Center Power Supply Rack PDU PDU PDU UPS ATS

    GEN Utility Transformer Utility Transformer GEN ATS UPS PDU PDU PDU
  7. Language Limitations • Single thread of execution* • Code that

    is executing has full control – May crash the process – May meddle with any data • Single thread limits error handling abilities
  8. Error Handling Insufficiencies • Unhandled exceptions always crash the application

    – Exceptions must be caught if the application is to continue running • Some exceptions cannot reasonably be handled inline – Software bugs are a common source of faults and often result in exceptions – Some potential exceptions are intentionally ignored – Impossible to enumerate all potential exceptions
  9. Caused by Lack of Isolation • Single thread of execution

    is the biggest weakness – Everything is under it’s control – No redundancy, we don’t have other threads of execution for backup • When a function calls another function it is passing it the all powerful thread of execution – There is no way for the original caller to take back this power – Rest of the application is powerless and must wait for the function to return – No, it’s not sending it a message
  10. True Isolation • Multiple threads of execution • Each with

    their own memory • No shared memory between them • Preemptive scheduling so CPU time is shared fairly among them
  11. Limitations of Libraries • Libraries can't enforce system wide-guarantees –

    Immutable data – Memory safety – Type safety • Libraries can't change architecture of the underlying language – Optimizations – Language constructs
  12. A new language is needed when we need to enforce

    additional constraints on our programs OR When features are needed that must be provided by the underlying language
  13. Erlang Processes • Not correlated with threads or processes –

    Not the same as an OS process • Each have their own memory – Each process is garbage collected individually • Preemptively scheduled – Busy processes won’t hog CPU time
  14. Erlang Processes • Identified by ID and optionally by name

    • Can communicate by placing messages in the mailbox of the recipient process • Can be created on the fly with the spawn command • Can be monitored by another process so the process can take action when the process crashes • Can be linked to another process so both processes crash when an exception occurs
  15. Erlang OTP • Processes alone aren’t enough – Processes only

    limit the effects of faults – Processes cannot restore faulting systems • OTP is a collection of libraries and tools for building systems that can recover from transient faults automatically
  16. Processes are Actors • Ends up feeling like a better

    OO • Best implementation of Alan Kay's vision as he described it at OOPSLA 1997 • Destroys some OO misconceptions that have been forced on us by our languages
  17. Data Types • All data is immutable Atoms • Atoms

    are just like symbols in Ruby • No boolean type, just the atoms true and false hello_world a true % No booleans
  18. Tuples • {one, two, three} % Tuples are contiguously in

    memory {1,2,3,4} % We can access individual items with element element(2, {1,2,3,4}) % => 2
  19. Lists • No array type, only linked lists. • Each

    item contains a pointer to the next them [1,2,3] Letters = [a,b,c] % Items can be added to the front of the % list easily [d|Letters] % => [d,a,b,c]
  20. Strings (Still Lists) • No true string type, strings are

    lists of character codes "Joe" % => "Joe" % still just a list % $a returns the character code for a $a % => 97 % If lists only contain character codes % they will be printed as strings [$a, $b, $c] % => "abc"
  21. More Data Types... • % Maps #{key => value} %

    Records -record(user, {username, email, password}). #user{ username="Joe", email="[email protected]" }.
  22. Modules • Modules must be defined in a file with

    the same name -module(demo). % Functions must be exported to be used % outside module -export([test/0]). % Function here...
  23. Functions • Functions are identified by name and arity %

    add/2 has two clauses add(0, 0) -> 0; add(X, Y) -> X + Y. % add/3 has one clause add(X, Y, Z) -> X + Y + Z.
  24. Pattern Matching a = a % => a a =

    b % => ** exception error: no match of right hand side value b Letter = a % => a Letter % => a
  25. Pattern Matching Tuples • {ok, Value} = {ok, "foo bar

    baz"} Value % => "foo bar baz" {ok, Value} = {error, crashed} % => ** exception error: no match of right hand side value crashed
  26. Pattern Matching Lists • [Head|Tail] = [1,2,3] Head % =>

    1 Tail % => [2,3] [First,Second,Third] = [1,2,3] Second % => 2 [One,Two] = [1,2,3] % ** exception error: no match of right hand side value [1,2,3] [First,Second|Rest] = [1,2,3]
  27. Underscore Variable • Can be used in place of a

    regular variable in a pattern • No values are bound to it, meaning it can match any value anytime it is used • It’s common to use it if we don’t care about a value in a pattern {_, _} = {1,1} {_, _} = {1,2} {Num, Num} = {1,2} % ** exception error: no match of right hand side value {1,2}
  28. Pattern Matching in Functions • Function clauses use pattern matching

    to determine which clause should be executed % add/2 has three clauses add(0, 0) -> 0; add(X, X) -> X * 2; add(X, Y) -> X + Y.
  29. Recursion • Recursive functions are functions that call themselves •

    Recursive functions are used when repetition is needed • If a function calls itself and never returns an infinite loop is created • Tail call and other optimizations so you never run out of stack space
  30. Process Messaging % `Pid` is a process ID Pid !

    {add, 1, 2, self()} % Receive a message in the process receive {add, X, Y, Caller} -> % Send the result back Caller ! add(X, Y) _ -> error end
  31. Spawning a Process • Processes will return until the function

    they are running ends or encounters an exception • Recursive functions are typically used for servers % Assuming ?MODULE:math_server/0 is a function {ok, Pid} = spawn(?MODULE, math_server, []).
  32. Math Server Demo • API for the caller • API

    calls send messages to the server, which does the arithmetic • Result is sent back to the client process via a message, which then causes the original call to return with the result • With and without OTP supervision
  33. Conclusion • Fault tolerance is at the center of Erlang’s

    design • Erlang gives us the constructs we need to build concurrent applications • OTP gives us the tools we need to build fault tolerant applications in Erlang • Erlang’s concurrency model enables Erlang to support things like distribution and hot code upgrades • Erlang is an ideal choice if you want a language that can scale with your company
  34. Things I Didn’t Cover • OTP behaviors • Metaprogramming •

    List comprehensions • Type checking with Dialyzer • And much more...
  35. Resources • Official Website - http://www.erlang.org/ • Online REPL -

    http://www.tryerlang.org/ • Free Book on Erlang - http://learnyousomeerlang.com/ • Programming Erlang Book - https://pragprog.com/book/jaerlang2/programming-erlang