Rubyists, have a sip of Elixir!
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 65 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/37637 (DOI) | |
Publisher | ||
Release Date | ||
Language | ||
Producer |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
Ruby Conference 201414 / 65
2
3
4
6
9
11
14
17
18
19
20
25
27
29
30
32
34
35
39
40
46
47
50
53
55
56
58
61
63
00:00
Storage area networkSession Initiation Protocol
00:26
Network topologyOffice suiteMultiplicationUniform resource locator1 (number)Concurrency (computer science)Point (geometry)Line (geometry)Rule of inferenceUML
01:29
Thread (computing)SynchronizationWechselseitiger AusschlussCodeAbstractionThread (computing)Concurrency (computer science)Line (geometry)Single-precision floating-point formatElectronic mailing listSynchronizationCondition numberVariable (mathematics)Sheaf (mathematics)Multi-core processorNeuroinformatikComputer programmingInternetworkingPoint (geometry)MicroprocessorOrder (biology)Type theoryRoundness (object)
02:14
MicroprocessorComputer programmingRoundness (object)Limit (category theory)FreewareSoftwareSerial portCore dumpInternetworkingOrder (biology)Process (computing)Raw image formatSoftware developerMultiplication
02:54
Video gameComputer programmingConcurrency (computer science)WritingFormal languageExpert systemAxiom of choiceComputer animation
03:21
Erlang distributionFormal languageAxiom of choiceOvalRow (database)Video gamePerturbation theoryConcurrency (computer science)Group actionArtificial lifeCodeStructural loadDistribution (mathematics)Fault-tolerant systemSoftware testingComputer animation
04:14
TouchscreenSoftware frameworkFormal languageFunctional (mathematics)Virtual machineMountain passParallel computingErlang distributionConcurrency (computer science)Real-time operating systemBuildingPhysical systemImage resolutionMeeting/InterviewComputer animationXMLUML
04:47
Armstrong, JoeErlang distributionSystem callGraph coloringPhysical systemFormal languageComputer programmingProgramming languageMultiplication signMultiplicationProcess (computing)Computer animationMeeting/Interview
06:11
Erlang distributionTable (information)Reverse engineeringScripting languageOffice suiteLibrary (computing)Computer animationLecture/Conference
06:45
Level (video gaming)Multiplication signMereologyDemo (music)Software repositoryPhysical systemLetterpress printingInteractive televisionLoop (music)Reading (process)
07:25
Software testingTask (computing)Formal languageUnit testingProjective planeMixed reality2 (number)
07:54
Operator (mathematics)Telephone number mappingFormal languageCodeCore dumpRange (statistics)Element (mathematics)System callWeightFunctional (mathematics)Square numberParameter (computer programming)Validity (statistics)Order (biology)UMLComputer animation
08:38
Hand fanLevel (video gaming)Digital filterOperator (mathematics)NeuroinformatikSeries (mathematics)Transformation (genetics)Functional (mathematics)Motion captureOperator (mathematics)Parameter (computer programming)Electronic mailing listComputer animation
09:08
Function (mathematics)Computer configurationTelephone number mappingElectronic mailing listResultantRootMappingData structureHash functionRoutingRule of inferenceSign (mathematics)LoginLecture/Conference
10:09
PiSign (mathematics)LoginBuildingConcurrency (computer science)Endliche ModelltheorieCategory of beingGroup action
10:36
Process (computing)Task (computing)Message passingType theoryShared memoryCategory of beingEndliche ModelltheorieConcurrency (computer science)Message passingProcess (computing)CoprocessorEntire functionTelecommunicationDependent and independent variablesSocial classLatent heatPattern matchingTask (computing)Semiconductor memoryMeeting/Interview
11:16
Computer programmingFormal languageProcess (computing)Operating systemConcurrency (computer science)Primitive (album)Physical systemCoprocessorErlang distributionVirtual machinePrincipal ideal domainLecture/ConferenceComputer animation
11:47
Process (computing)Message passingPrincipal ideal domainRadio-frequency identificationFunctional (mathematics)NeuroinformatikReal numberMathematicsMathematicianLogicComputer animationXMLUML
12:29
Function (mathematics)Network topologyNumberCASE <Informatik>Functional (mathematics)Parameter (computer programming)ResultantFunction (mathematics)Computer animationLecture/Conference
12:57
Function (mathematics)Loop (music)Functional (mathematics)Process (computing)Concurrency (computer science)NeuroinformatikMultiplication signLoop (music)MereologyNetwork topologyMessage passingPoint (geometry)Parameter (computer programming)Computer animationLecture/Conference
13:39
Loop (music)Message passingParameter (computer programming)Functional (mathematics)Module (mathematics)Radio-frequency identificationProcess (computing)Computer animation
14:11
Loop (music)Message passingLoop (music)Virtual machinePattern languageProcess (computing)Erlang distributionSpeicherbereinigungFormal language2 (number)Matching (graph theory)ResultantLetterpress printingFunctional (mathematics)Computer animation
14:52
Process (computing)BefehlsprozessorMessage passingBuffer solutionNeuroinformatikProcess (computing)Goodness of fitFunctional (mathematics)Complete metric spaceMoment (mathematics)Computer hardwareGastropod shellResultantCore dumpDirection (geometry)Message passingOperator (mathematics)Block (periodic table)CASE <Informatik>Graph coloringSystem callException handlingAeroelasticityQueue (abstract data type)Sinc function
17:25
Virtual machineGraph coloringPhysical systemErlang distributionFault-tolerant systemComputer animation
17:57
DreizehnNetwork topologyHierarchyVirtual machineProcess (computing)Fault-tolerant systemNetwork topologyComputer animation
18:25
FIESTA <Programm>Hill differential equationProcess (computing)Network topologyOrder (biology)Computer animation
19:04
Process (computing)System callComputer programmingProcess (computing)Boss CorporationGroup actionControl flow1 (number)LeakMortality rateCrash (computing)Demo (music)Multiplication signHierarchyCoprocessorComputer animation
20:25
Crash (computing)Multiplication signComputer programmingProgrammer (hardware)Control flowSoftware bugProcess (computing)HierarchyPhysical systemSeries (mathematics)IterationMereologySoftware testingComputer animation
20:54
IterationSoftware testingSeries (mathematics)MereologyStructural loadWebsiteComputer programmingNumberTotal S.A.FlagUniform resource locatorComputer animation
21:28
View (database)Sign (mathematics)FreewareSoftware testingPoint cloudDemo (music)Process (computing)Message passingNumberTrailProcess (computing)Computer programmingSimilarity (geometry)Service (economics)Interactive televisionCoordinate systemLecture/ConferenceComputer animation
21:57
Process (computing)Error messageProcess (computing)Message passingCoordinate systemConcurrency (computer science)NumberComputer animation
22:26
Execution unitBendingError messageConcurrency (computer science)Process (computing)Coordinate systemResultantMultiplication signCore dumpClient (computing)Dependent and independent variablesError messageCASE <Informatik>Functional (mathematics)Different (Kate Ryan album)Web browser
23:02
Software bugError messageCodeHost Identity ProtocolModule (mathematics)Multiplication signFunctional (mathematics)Error messageElement (mathematics)TupleCore dumpWeb browser
23:30
Core dumpProcess (computing)Module (mathematics)Error messageProcess (computing)Coordinate systemCodeCore dumpArithmetic meanDifferent (Kate Ryan album)Revision controlCASE <Informatik>Functional (mathematics)Principal ideal domain
24:05
CASE <Informatik>NumberInclusion mapError messageCore dumpCASE <Informatik>Process (computing)Message passingNumberTotal S.A.Coordinate systemResultantFunctional (mathematics)Point (geometry)Line (geometry)Computer programming
24:36
Core dumpParsingInfinityTask (computing)SynchronizationComputer programNormed vector spaceFunctional (mathematics)Point (geometry)Process (computing)Computer programmingCoordinate systemResultantParameter (computer programming)Food energyEndliche ModelltheorieMoment (mathematics)Task (computing)AnalogyNeuroinformatikXMLUML
25:43
Task (computing)SynchronizationInfinityTask (computing)Parameter (computer programming)Data conversionHypermediaSoftware testingComputer animation
26:30
Core dumpTask (computing)Telephone number mappingParsingInfinityCoordinate systemProcess (computing)Task (computing)ResultantMessage passingSoftware testingStructural loadCASE <Informatik>Core dump
27:12
Core dumpTask (computing)SynchronizationInfinityParsingComputer programTelephone number mappingConcurrency (computer science)Order (biology)CASE <Informatik>Structural loadCodeSoftware testingConcurrency (computer science)CuboidFunctional (mathematics)Computer animation
27:46
InfinityRun time (program lifecycle phase)Erlang distributionPhysical systemConcurrency (computer science)Group actionOrder (biology)Structural loadSoftware testingDistribution (mathematics)Uniform resource locatorProcess (computing)Rule of inferenceMessage passingSoftwareCoprocessorComputer animation
28:26
Digital filterComputer programVertex (graph theory)Task (computing)InfinityTelephone number mappingLevel (video gaming)Software testingStructural loadLine (geometry)Process (computing)Thermal conductivityComputer configurationFunctional (mathematics)Connected spaceElectronic mailing listStatisticsTask (computing)AdditionMusical ensembleInheritance (object-oriented programming)System callProgram flowchart
29:12
Task (computing)Vertex (graph theory)Level (video gaming)Telephone number mappingInfinityCodeTask (computing)Coordinate systemAlgebraFunctional (mathematics)Parameter (computer programming)Message passingProgram flowchart
29:47
InfinityTask (computing)Telephone number mappingLevel (video gaming)Vertex (graph theory)ResultantLocal ringRemote procedure callProcess (computing)Ferry CorstenStructural loadDistribution (mathematics)CodeSoftware testingProgram flowchart
30:16
Programmer (hardware)DemosceneResultantProjective planeCellular automaton
31:00
Software frameworkConfluence (abstract rewriting)Socket-SchnittstelleWeb 2.0Projective planeGreen's functionFreezing
31:32
System callComa BerenicesSlide ruleMultiplication signFreewareVulnerability (computing)Client (computing)Concurrency (computer science)Functional programmingComputer animation
32:16
Multiplication signSoftware developerConcurrency (computer science)Formal languageSoftware maintenanceFunctional programmingWordProgrammer (hardware)System callComputer programming
33:25
SoftwareEvent horizonVideoconferencing
Transcript: English(auto-generated)
00:19
I'm super excited to be here.
00:21
My name is Benjamin, and today I'm inviting everyone to have a sip of elixir. I'm from Singapore, and I took three flights and 20 hours just to get here and join everyone over here at RubyConf. Thank you.
00:43
So I'll do the obligatory employer thing. My trip has been made possible by Neo, who has kindly sponsored my tickets and accommodation. Obviously, we are hiring. We have offices in multiple locations in the US, and we have one in Singapore.
01:01
Please come to speak to me if you're interested. Also, a huge thank you to the RubyConf Committee for organizing this entire conference. It's amazing. And also giving me an opportunity to come and speak to all of you.
01:21
And I must say, the RubyConf Committee has a great taste in choosing my talk. I have a confession. I have never written a single line of code using thread.new in Ruby. Threads somehow feel like the wrong kind of abstraction
01:41
to think about concurrency. New taxes, synchronization, condition variables, critical sections, and the list goes on. So many different ways to shoot yourself in the foot. I persevered. I love Ruby, but concurrency wasn't one of Ruby's strongest points,
02:00
as you've seen in various other talks. Yet, I wanted to be able to program concurrently. I wanted to be able to program for multi-core computers without losing my sanity. In 2005, a famous article titled The Free Lunch is Over made its rounds
02:20
around the internet. It stated that the speed of serial microprocessors was already reaching its physical limit. This means that in order to increase performance, companies such as Intel or AMD had to, instead of increasing the raw clock speed, had to squeeze in more cores into a single chip.
02:42
More importantly for us software developers, this means that we will be forced to write massively multi-threaded programs to make use of such processes. So now, not only I couldn't write concurrent programs, but someone was not going to give me any free lunch.
03:01
Life was starting to look pretty bleak. I stumbled onto Elixir mostly due to the hype. I've been playing with it a little over a year now, which makes me an Elixir expert, but I am really having so much fun, I think it will be almost criminal not to share this with you.
03:26
So of course, I'm not coming to a Ruby conference and asking you to switch languages. Instead, I'm encouraging each and every one of you to be more promiscuous in your languages. Elixir just happened to be the language choice I picked.
03:43
Here's what we'll learn today. We'll look at Elixir's tooling, and we'll also look at the concurrency and fault tolerance features in Elixir. I have recorded a few examples because live coding is hard, so we can see some Elixir code in action.
04:01
Finally, we will build a very simple HTTP load tester, where we can see concurrency and distribution come together. Lots of interesting things to learn, many fun things to do. Let's do this. So Elixir is created by Jose Valim.
04:20
You might know him from his work with such things such as device and some Ruby framework. In a nutshell, Elixir is a functional and concurrent language built on the Erlang virtual machine. You might know that Erlang excels in building soft, real-time concurrent distributed systems,
04:44
and its reliability is pretty legendary. I hope not many people around here have used Erlang before. Otherwise, you will notice a lot of loopholes in the story I'm gonna tell you next. Erlang was born in Eriksen's CS lab
05:00
in Stockholm, Sweden. Joe Armstrong, and along with these three fine gentlemen created Erlang. Eriksen wanted to find a better way to program the telephone switch. Here's roughly how a telephone switch works. A caller makes a phone call,
05:21
and the request arrives at the switch. The switch will then connect to the receiver. Obviously, the switch would have to be able to handle multiple calls coming in and out, but not only that, each of the telephone switch should be able to communicate with each other.
05:41
Eriksen, during that time in the 1980s, had a programming language that could run on these telephone switches. Unfortunately, there were two problems. The first one was it took way too long to write programs in that language, and secondly, that language had a problem
06:00
in that it couldn't turn these telephone switches into true multiprocessor systems. Erlang was therefore created to suit these needs and to tackle this problem. This few relatively small and obscure companies use Erlang. You might be able to recognize some of them.
06:21
So what does Elixir bring to the table then? Is it just another coffee script for Erlang? Thankfully, not so. These are some of the things which Elixir offers which improve upon Erlang. Not only that, using Elixir enables you
06:41
to use Erlang libraries, and the reverse is also true. So here comes the part where I try to convince you why Elixir is worth your time. Let's first talk about the tooling. The first tool I'm gonna show you is Interactive Elixir, or IEX for short.
07:00
In the Ruby world, it's IRB. This is a repo or read eval print loop that you will spend most of your time in. This demo will show you how Elixir looks like and it also shows you the built-in documentation system which is written in Markdown.
07:27
The second tool I'm gonna show you is Mix. Mix allows you to create an Elixir project quickly and has tasks to handle things like installing dependencies and running unit tests.
07:55
So we are now gonna see some Elixir code. Allow me to introduce what I consider to be one of the most awesome language feature in Elixir,
08:03
the pipe. Check this code out. This is valid Elixir code. Stare at it for five seconds and try to figure out what it's trying to do. This code takes a range of one to 10, squares each element,
08:21
and then selects elements which are larger than 10. No big deal. I think this code is terrible. Notice how, in order to understand this code, you somehow must locate the first argument in the innermost function and then work your way slowly out. Using pipes, we can express the same computation
08:42
in a much prettier way. In fact, you can view this computation as a series of data transformation. Turns out, there's an even shorter way of expressing the previous computation using the function capture operator. The outermost ampersand expands
09:01
to the anonymous function, while the ampersand one represents the first argument in the function. So let's see a slightly more realistic example. Here, I want to parse the list of places given this JSON. Here's one way we can parse this JSON using pipes.
09:25
When we execute the get body, another copy of the JSON hash is returned, with result as its root node. Notice I said copy. This is because in Elixir, data structures are immutable. This means that when you modify a data structure,
09:41
a modified copy is returned, leaving the original one untouched. Similarly, get result returns places as its root node. And finally, we get a list of places. And from there, it's just a matter of mapping through all the places and processing them accordingly.
10:03
So let's give our brains a little break, and I'll show you some interesting things about Singapore along the way. This is a typical road sign in Singapore. I've lived in the US for one year, and seriously, US has really nice road signs.
10:20
We love our anchor names, and everything circled here is either a name of an expressway or a building. In Singapore, we love our anchor names so much that we even have a Wikipedia entry on it. Before we go any further, let's talk about the actor concurrency model in Elixir.
10:42
In general, the actor concurrency model has the following properties. When we talk about actors, they are also called a process that performs a specific task and communicates using sending and receiving of messages. Actors respond to really specific messages.
11:04
In Elixir, these messages are pattern matched. Finally, processors do not share memory. This eliminates a whole entire class of concurrency gotchas. Now, let's go to the fun stuff. We will see how to write a concurrent program in Elixir.
11:23
Processors are the basic concurrency primitive in Elixir, but do not confuse this with operating system processors. They are not the same. These processors are independently created and managed by the Erlang virtual machine. This is a process, and that is a process ID.
11:41
If I'm lazy, you will hear me refer to the process ID as a PID for short. A process communicates by sending and receiving messages. If you know the PID of any process, you can send it a message. Messages are sent asynchronously,
12:00
much in a fire and forget fashion. This means that once a process sends a message, it returns immediately and continues to handle the next computation. Allow me to introduce you the Ackermann function. In my opinion, this is my favorite hello world example. While using math functions as examples
12:20
is pretty annoying sometimes, I have a perfectly legit reason, so bear with me. We will see more real world examples soon. Take a look at this function. This function takes in two arguments, m and n, of which both must be zero or more. The first two cases are pretty straightforward.
12:40
It's the third case that gets interesting. Look at the third case. When both m and n are larger than zero, the second argument calls itself. This means that its value grows rapidly and even for really small outputs. For example, Ackermann 4-3 results in a ridiculously huge number.
13:04
This is the Ackermann function in Elixir. We will now take a look at our Ackermann function again, but this time we will see how we can use processes. The reason we want to do this is to have concurrency. That is, we can fire multiple computations
13:21
at the same time. The top part we have seen before, that's the usual Ackermann function. The loop function, that's new. When the loop function is executed in a process, the process then can send and receive messages. Let's see how we can do that. To create a process, we use the spawn function.
13:43
The spawn function takes in three arguments, the module name, the function name, and the arguments of the function. The return value of the spawn function is a pit. Now our process is ready to receive and send messages.
14:01
Let's send the process W1 a message. The built-in send function takes in the process ID and the message that we want to send. The sent message is then pattern matched in the receive block. When the pattern matches, the body is executed.
14:23
Finally, the loop recursively calls itself so that it can handle the next message. Without the loop, the process dies and will get garbage collected by the Erlang virtual machine When the process receives anything other than a two-element tuple,
14:41
the second catch-all pattern is matched. Similar to the previous example, the body is matched and then the result is printed. I want to show you that we can run functions directly. That is, we are not running the functions in a process.
15:06
For simple computations, that's probably fine, but the moment you hit into more computationally intensive operations, you will block the caller. In this case, when we give it a very hard job to handle,
15:21
the IEX session will be blocked and will only be unblocked once the computation is done. Things get a little more fun now. We'll create a process to respond.
15:41
We will send the process the exact same message as before but since we are running in a process, this will not block the IEX session. Again, notice for simple jobs, the result returns almost immediately.
16:01
But for more complex jobs, the message is returned but the caller is not blocked. We will have to wait a while more for the result to appear. But unlike in the previous case, the shell session is not blocked in any way.
16:23
Let's take things up a notch. We are gonna start four processes and give each of them a computationally intensive job to handle.
16:43
So this computer has four cores in it and look at it, all four cores are littered up completely. I always get a warm fuzzy feeling
17:01
when I put my hardware into good work. So what happens when we send a process where we send a message to a busy process? All that happens is the messages will get buffered. As you see there, something interesting about Singapore.
17:28
Guess what all these bunch of people are queuing up for? So in Singapore, we love to queue for stuff. We love to queue for coffee, bubble tea, freebies, stuff.
17:48
Let's talk about one of the coolest thing that Elixir inherits from the Erlang virtual machine. Fault tolerance is the system's ability to stay up in the presence of failures.
18:02
Supervisors are an example of how the virtual machine implements fault tolerance. The green ball is the supervisor. It is just a process. Its only job is to monitor child processes. But supervisors can also be supervised. This means that we can create supervision trees
18:21
that are layered to form an even bigger supervision tree. When a child process dies, the supervisor can react in a couple of ways. For example, it can simply restart the failed child.
18:48
Here's another way the supervisor can react. Let's assume the same child process died. The supervisor can also terminate all the child processes under the tree
19:01
and then restart the child processes in the order they were created. I'm now gonna show you a demo of how a supervisor restarts a child process.
19:20
So these are the processes started out when you launch an IEX session. The green and the blue balls are processors. The green stuff you can basically ignore. So I'm gonna create 50 worker processors in one of the supervisors.
19:51
See what happens when I kill everything. The supervisor automatically starts up everything again.
20:00
Now I'm gonna create more workers. Isn't that awesome?
20:26
Lang and Elixir programmers have a let it crash motto. In general, we do not spend so much time on defensive programming. Somebody is bound to trip over the wire, your bugs is gonna have code, stuff happens. Instead, they build supervisor hierarchies
20:42
to make sure that when something breaks or does blow up, another process can take over and restore the system into the next good state automatically. We've come to the last part and I think the coolest part of my talk. Let's build a very simple HTTP load tester.
21:02
We'll build our load tester in a series of iterations and the first one will obviously be the most simplest. The load tester is implemented as a command line program. I've called the load tester Blitzy. The program takes in an end flag followed by a number which states
21:20
the total number of workers to run. This is then followed by the URL of the site we want to run against. Any similar sounding service is purely coincidental. Let's try to understand first the interaction between the processes. When we launch a program, a coordinator process is started up
21:42
and a bunch of workers are created. First, we tell the coordinator process how many workers it has to handle. The coordinator also keeps track of the number of workers it has heard from. It is initially set to zero. The worker, on completing a successful GET request,
22:02
sends the coordinator process a success message. After receiving a message from the worker, the coordinator process then increments the number of workers it has heard from by one. Say another worker sends over a failed message. Same thing, the coordinator increases the counter
22:21
and now it has to wait for the very last worker. The first version, the simplest one. Simplest because we will not be using any concurrency here. The worker process is not complicated. Its only job is to make a GET request,
22:41
time it, and then send back the results to the coordinator process. The worker can receive at least two different kinds of responses from the HTTP client. In this case, we are only concerned when the HTTP client returns a successful response or timeout errors.
23:03
If the GET request is successful, the first do request function clause will be matched and the time elapsed is returned. Otherwise, it will return a tuple with an error as its first element. An error unknown tuple is returned
23:21
for any other return value from the HTTP client. So one of these values will eventually be sent to the coordinator process. Let's see how the coordinator process looks like. This is the code for the coordinator process.
23:40
We first give the coordinator process a name. In this case, it's the same name as the module name. When a process is registered, it can be accessed using its name instead of its PID. The main work is done in the do process workers function. We define two different versions of do process workers
24:01
to handle two very specific cases. What cases are there? The first one is the base case. It is when the number of process workers equals to the total number of workers we have heard from. This means that a coordinator process has heard from n number of workers
24:20
and therefore it knows it can return the result. Otherwise, we know that we have to wait for a worker to send us another successful message like you see here, or a failure message. The entry point of our command line program is the main function.
24:43
The do request function is where we start the coordinator and the worker processes. I want to take a slight detour and talk about tasks. A task is a little like a feature if you're familiar with them. So, let me try to explain by way of an analogy.
25:02
When you create a task, you not only create a process, it comes with a container. So, when you create a task, you put in the module, you put in the function, and it does the computation in a container. And it runs in the background. The moment you want to find out, hey, what value is in it, you call task.await
25:22
and you peek inside the container and check if the value is there. If the task is busy, you have to block. That's the only thing with tasks. So, a task allows you to do some work in a separate process and lets you easily collect the results afterwards when you need it.
25:44
Running a task is very simple. You call task.async and pass in the necessary arguments. When you're ready to retrieve the result, you simply call task.await. Let's see an example.
26:07
So, again, we're running the Ackermann example over here. And for simple computations, it returns immediately. More complicated ones, you have to wait.
26:27
And there you go. Back to our HTTP load tester. We start the coordinator process in a task. A coordinator process is started in a separate process
26:40
and then now is waiting for workers to talk to it. Each worker, in this case, is started one by one. The problem here is that each worker must complete the GET request before the execution of the next worker. So here, we do not have concurrency.
27:00
Finally, task.await is then called to retrieve the return value of the coordinator process. That is, the accumulated results from the messages received by the workers. Let's see an example run. Notice in this case that the workers
27:21
are returned in order of creation. Now, let's make our load tester concurrent. How much code do you think we need to add in this case? The only thing we change is in the red box. We use the spawn function to create
27:40
and launch a separate process for each worker. That's it. The workers now run concurrently. Let's see this in action. There you have it. The workers do not come in any order.
28:01
Finally, let's make our load tester distributed. Here, we have two nodes that are connected by the same network. Processors in Erlang and in a cluster are location transparent. This means that message passing between processes on the same node is just as easy as sending a message between two different nodes,
28:22
as long as you know the process ID. To have our load tester run distributed, we have to do slightly more work. First, we have to connect up our nodes. We first set up the current node as the master node.
28:41
This line connects to all the slave nodes. We then pass a list of connected nodes to the process options function. Process function calls do request, which is what you see here. First, we calculate how many workers
29:00
we should run on each node. So for a four node cluster with an n value of 1000, we are gonna have 250 workers spawned on each node. Here, we are doing something super cool. The code over here starts up the coordinator task remotely on each of the four nodes.
29:22
What is written is a list of tasks, three of which come from the remote nodes, and one of them, the main one. Next, we're gonna start up 250 workers on each of the four nodes. All we need to do here is to iterate through each node, spawn the workers remotely using the node.spawn function,
29:44
and pass in the necessary arguments. This is what we're after. Finally, just as before, we call task.await to collect back our results from the local and remote nodes, and local and remote coordinators,
30:02
once the worker processes have completed their jobs and exited. This is really all the code you need to set up and run the HTTP load tester to run distributedly. Let's see an example run.
30:24
We first start up three slave nodes, and then we run the main program, and we are done. We are running distributedly about Singapore.
30:44
This is a common scene in food courts in Singapore. This is how we reserve seats. We use anything from tissue packets, bags, cell phones, and if you happen to be a doctor, we also use stethoscopes.
31:01
The Elixir community is growing pretty nicely. One of the most popular projects is the Elixir, is the Phoenix framework, created by Chris McCott. One of his really nice features is that it makes working with web sockets really simple. George Adams has also created Elixir Sips, modeled something like Avdi Grimm's Ruby Tapas.
31:23
Totally worth checking out. There's an Elixir conference held this year by Jim Fries, who is in the audience, and there's another one next year, this time in Poland. In my copious free time, I blog about Elixir stuff, mostly.
31:43
And if you want to learn more, there are already some books available, but more importantly, I'm also writing a book, and currently waiting for my publisher to get it in the hands of readers. So I need to thank two ladies. One is Heather Miller, whose slight designs I shamelessly copied.
32:01
The other is my wife, who allowed me to ignore her during the preparation of this presentation. And also my teammate, Neil, who has been super supportive for me going conferences to speak at and not doing client work. If you haven't started worrying about concurrency yet,
32:21
I think it's a perfect time to be paranoid. The world is concurrent, but how we program isn't. I also think this is the best time to get into functional programming. Dave Thomas said it best at the recent GoTo conference at Chicago. He said, and I quote, there is a word for people
32:40
not doing functional programming five years from now. That word is maintenance programmer. Elixir has opened up many opportunities for learning personally. I'm having so much fun learning about functional, concurrent, and distributed programming, and I encourage you to go out and try out different languages.
33:02
Find your own Elixir. It is truly a wonderful time to be a developer now. Thank you all for being a wonderful, wonderful audience, and I would love to answer any questions you have. I'm a very shy person, so if you come up to me after my talk, I would be more than happy to speak to all of you. Thank you very much.