Pro Yearly is on sale from $80 to $50! »

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.

9fa60df551b9e4282c0519bf173c2e04?s=128

Trevor Brown

July 20, 2017
Tweet

Transcript

  1. Why Erlang? Trevor Brown

  2. Trevor Brown Sarasota, Florida Erlang, Elixir, Ruby, JavaScript Software Developer

    at Voalte
  3. 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
  4. 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
  5. Potential Faults - Software • Again, software faults will be

    encountered • Unanticipated hardware failures • Software bugs present in other systems • Software bugs in your own code
  6. 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
  7. Most Modern Languages Don’t Handle Faults Well

  8. 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
  9. Let’s look at how fault tolerance is handled in hardware

    systems...
  10. Data centers have systems in place that ensure their servers

    remain online
  11. Data Center Power Supply Rack PDU PDU PDU UPS ATS

    GEN Utility Transformer Utility Transformer GEN ATS UPS PDU PDU PDU
  12. Fault tolerance is achieved through isolation and redundancy

  13. Fault removal is also necessary for long term reliability

  14. Software reliability can be achieved the same way

  15. This cannot be done with most language runtimes

  16. 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
  17. 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
  18. 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
  19. How do we solve this?

  20. 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
  21. Can support for this be added to existing languages via

    libraries?
  22. 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
  23. 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
  24. Erlang

  25. How does Erlang solve this?

  26. 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
  27. 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
  28. 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
  29. Erlang VM • Concurrent • Distributed • Mostly functional •

    Dynamically typed • Hot code loading
  30. Language Priorities Runtime guarantees syntax ecosystem developer friendliness

  31. Erlang Language Constructs • Spawning processes • Message passing between

    processes • Recursion • Pattern matching
  32. 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
  33. Erlang Basics

  34. 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
  35. Binaries and Numbers • % Binaries <<97,98,99>> <<"abc">> % Integers

    12 % Floats 23.5
  36. 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
  37. 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]
  38. 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"
  39. More Data Types... • % Maps #{key => value} %

    Records -record(user, {username, email, password}). #user{ username="Joe", email="joe@ericsson.com" }.
  40. 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...
  41. 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.
  42. Pattern Matching

  43. Pattern Matching a = a % => a a =

    b % => ** exception error: no match of right hand side value b Letter = a % => a Letter % => a
  44. 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
  45. 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]
  46. 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}
  47. 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.
  48. Recursion

  49. 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
  50. Recursion sum_list(List) -> sum_list(List, 0). sum_list([], Acc) -> Acc; sum_list([Head|Tail],

    Acc) -> sum_list(Tail, Acc + Head).
  51. Processes

  52. 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
  53. 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, []).
  54. 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
  55. Math Server Demo <0.97.0> Math Server <0.59.0> Shell Process (Us)

    <0.83.0> start {add, 1, 2} {response, 3}
  56. Demo

  57. Conclusion

  58. 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
  59. Things I Didn’t Cover • OTP behaviors • Metaprogramming •

    List comprehensions • Type checking with Dialyzer • And much more...
  60. 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
  61. Trevor Brown @Stratus3D Github.com/Stratus3D stratus3d.com admin@stratus3d.com https://github.com/Stratus3D/why_erlang