Elixir Is Cool: But what can you actually do with it?
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 |
| |
Alternative Title |
| |
Title of Series | ||
Number of Parts | 96 | |
Author | ||
License | CC Attribution - NonCommercial - 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/51711 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
NDC Oslo 201646 / 96
2
7
8
9
12
14
19
20
26
28
31
33
38
40
43
45
48
50
51
61
63
65
76
79
80
83
87
88
90
93
94
96
00:00
WebsiteProcess (computing)BlogArithmetic meanLevel (video gaming)Coma BerenicesProduct (business)UML
01:19
CodeMultiplication signVideoconferencingWebsiteLine (geometry)Process (computing)Focus (optics)Computer science
02:07
Reading (process)Annulus (mathematics)Software frameworkWorld Wide Web ConsortiumDifferent (Kate Ryan album)Data miningElectric generatorWebsiteFocus (optics)Software frameworkData structureUltraviolet photoelectron spectroscopyMobile appGateway (telecommunications)NeuroinformatikWeb 2.0BitFrustrationQuicksortFormal languageLevel (video gaming)PlanningGreatest elementPoint (geometry)Process (computing)Punched cardSlide ruleRight angleGodLine (geometry)ResultantECosJSON
04:37
Process (computing)TelecommunicationSpeech synthesisSoftware frameworkShift operatorBuildingCodeComputing platformSlide ruleOpen setComputer programmingExpert systemTerm (mathematics)Erlang distributionComputer animation
05:18
Speech synthesisExpert systemPoint (geometry)GoogolDatabaseMereologyProcess (computing)Analytic setTraffic reportingUniform boundedness principleInformationComputer animation
06:43
BitRight angleClient (computing)WritingProcess (computing)CodeUniform resource locatorWave packetMultiplication signSoftware developerSoftware frameworkCartesian coordinate system
07:40
Ferry CorstenProgrammer (hardware)WordVideo gameFormal languageMultiplication signCartesian coordinate system.NET FrameworkSoftware frameworkMonster groupMultiplicationCore dumpType theoryCodeFigurate numberMobile appErlang distributionExpressionNumberSoftware bugProcess (computing)Vulnerability (computing)SineResultantData managementGoodness of fitComputer iconPoint (geometry)Product (business)Scripting languageTypprüfungArithmetic meanComputer animation
09:51
Erlang distributionErlang distributionShift operatorRight angleJSONXMLComputer animation
10:28
Decision tree learningSocial classField (computer science)Default (computer science)Message passingModule (mathematics)Software repositoryLogicRow (database)Pattern languageNormed vector spaceDecision tree learningComputational scienceCodeComputer sciencePlastikkarteValidity (statistics)Uniform boundedness principleMathematicsSlide rulePattern languageDatabaseModule (mathematics)Row (database)CollisionRepository (publishing)Set (mathematics)Field (computer science)Different (Kate Ryan album)Endliche ModelltheorieRight angleMereologyReal numberOperator (mathematics)ECosSuite (music)Type theoryData structureGraph coloringSoftware frameworkCartesian coordinate systemNumbering schemeOffice suiteLevel (video gaming)Software repositoryComputer animation
13:10
Set (mathematics)Order (biology)2 (number)Library catalogDecision tree learningRight angleDifferent (Kate Ryan album)BitSet (mathematics)Software frameworkBuildingNetwork topologyBinary codeUtility softwareFront and back endsSoftware developerProcess (computing)DataflowProjective planeFlagComputer animation
14:59
Library catalogProduct (business)Module (mathematics)Thread (computing)Source codeInteractive televisionState observerQueue (abstract data type)Local GroupData dictionaryIntrusion detection systemFunktorProcess (computing)CASE <Informatik>Execution unitSoftware testingAnalogyError messageState of matterProcess (computing)Software testingLibrary catalogNetwork topologyStructural loadCodeCoroutineModule (mathematics)Computer fileMultiplication signScripting languageBitCartesian coordinate systemDisk read-and-write headCASE <Informatik>2 (number)Erlang distributionLink (knot theory)Shift operatorElectronic mailing listServer (computing)Mobile appInformationObject-oriented programmingUnit testingOperating systemType theoryRight angleParameter (computer programming)Mixed realityHash functionLengthReal numberProduct (business)Group actionArmstrong, JoeFormal grammarGrand Unified TheoryState observerPoint (geometry)Universe (mathematics)WaveDecision tree learningDirectory serviceLibrary (computing)Formal languageOrder (biology)Cellular automatonTerm (mathematics)Functional programmingLie groupExtension (kinesiology)WebsiteSystem callLevel (video gaming)Transformation (genetics)Field (computer science)Utility softwareSemiconductor memoryObservational studyXML
23:13
Process (computing)Error messageNetwork topologyMereologyCodeMultiplication signState of matterException handlingBlock (periodic table)Cartesian coordinate systemSource code
23:59
Network topologySlide ruleProcess (computing)Moment (mathematics)Metropolitan area networkCartesian coordinate systemComputer animation
24:39
Strategy gameExecution unitCASE <Informatik>Library catalogPhysical systemErlang distributionState observerResource allocationModule (mathematics)Software repositoryProduct (business)Telephone number mappingProduct (business)Process (computing)Semiconductor memoryRight angleDatabaseKey (cryptography)Network topologyState of matterSoftware repositoryState observerLibrary catalogMereologyCodeCartesian coordinate systemModule (mathematics)Row (database)Functional (mathematics)BitDefault (computer science)Greatest elementSet (mathematics)System callLibrary (computing)MappingDifferent (Kate Ryan album)NP-hardMultiplication signDivisorMetreTerm (mathematics)SineEndliche ModelltheorieShift operatorMonster groupWordOvalRadical (chemistry)Line (geometry)Arrow of timeOperator (mathematics)Server (computing)Query languageAbstractionCoroutineInheritance (object-oriented programming)Link (knot theory)Plug-in (computing)Generalized linear modelMobile appErlang distributionCore dumpFerry CorstenSkewnessComputer animation
29:52
Strategy gameProduct (business)Information Technology Infrastructure LibraryKey (cryptography)Decision tree learningLibrary catalogLocal area networkString (computer science)Order (biology)Lie groupMessage passingEndliche ModelltheorieProcess (computing)NumberSoftware frameworkDependent and independent variablesPattern matchingFormal languageWeb 2.0CodeFront and back endsFunctional (mathematics)Information overloadObject (grammar)BitBuildingInformationDecision tree learningParameter (computer programming)Semiconductor memoryMultiplication signLine (geometry)Library (computing)MereologyPoint (geometry)Constructor (object-oriented programming)Application service providerOrder (biology)Web pageCodeDatabaseMathematicsCASE <Informatik>Error messageStatement (computer science)System callCombinational logicCartesian coordinate systemHydraulic jumpFraction (mathematics)ResultantHTTP cookieRight angleEntire functionData storage deviceGame controllerCellular automatonStructural load19 (number)Web serviceComa BerenicesSelectivity (electronic)Disk read-and-write headOperator (mathematics)Web applicationPositional notationPattern languageContext awarenessWebsiteSingle-precision floating-point formatJSON
36:17
DatabaseLink (knot theory)DatabaseTelecommunicationMetropolitan area networkComputing platformProcess (computing)Computer programmingRight angleTerm (mathematics)Multiplication signDecision theoryPower (physics)Server (computing)Erlang distributionVirtual memoryArmstrong, JoeMeeting/Interview
37:29
Executive information systemDatabaseType theoryInheritance (object-oriented programming)Data storage deviceRead-only memoryKey (cryptography)Product (business)Decision tree learningChi-squared distributionError messageChinese remainder theoremInstance (computer science)Process (computing)Computer configurationMiniDiscOrder (biology)BuildingWritingGateway (telecommunications)Dependent and independent variablesAxiom of choiceServer (computing)Decision theoryPoint (geometry)InformationErlang distributionDatabaseSemiconductor memoryData storage deviceDecision tree learningMathematicsLoginState of matterResultantMultiplication signStructural loadTerm (mathematics)Traffic reportingUniform boundedness principleData miningFocus (optics)BitDrop (liquid)Right angleType theoryCrash (computing).NET FrameworkSingle-precision floating-point formatOffice suiteSequelSystem callDenial-of-service attackQuicksortWebsiteComputer animation
41:16
Cartesian coordinate systemProcess (computing)Row (database)Order (biology)Right anglePeer-to-peerDifferent (Kate Ryan album)DatabaseMusical ensembleData storage deviceDressing (medical)MassMultiplication signBitJSON
42:23
AliasingError messageCore dumpLogarithmMessage passingOrder (biology)BlogSoftware frameworkBuildingDifferent (Kate Ryan album)World Wide Web ConsortiumPattern languageSystem administratorOrder (biology)EmailMotion captureCodeOperator (mathematics)Software frameworkConstructor (object-oriented programming)PlastikkarteElectronic program guideMultiplication signSeries (mathematics)System callWeb 2.0Cartesian coordinate systemLine (geometry)Magnetic stripe cardProcess (computing)TouchscreenDifferent (Kate Ryan album)TwitterComplete metric spaceInstance (computer science)Computer animation
45:12
BitLink (knot theory)SineEvent horizonUML
46:46
Computer animation
Transcript: English(auto-generated)
00:04
Oh, wow, thank you guys for coming, it's almost the end of the day, and wow, I did not expect this many people to be here, but thank you. Thank you very much for coming. So today I'm going to talk about, can you guess? I'm going to talk about Elixir. If you've been around me in the last few months at all,
00:23
you know that I've kind of drank the Kool-Aid on Elixir in a big way. So it's actually one of the reasons that I wanted to put this talk together, is because as I'm rambling on about Elixir with friends and people that I meet, they always say, well, that's neat, the syntax is neat, and yeah, sure, I get it, Erlang, OTP, fast, resilient, blah, blah, blah, blah, blah. What can you actually do with it?
00:42
Have you built anything with it? Have you deployed anything with it? And the answer is like, well, I'm trying, I'm trying, because you can't just go and get a job, unfortunately, not just yet. Elixir is still kind of small, but it's growing. So anyway, I put together this talk just for that reason. So what I did is I decided to port an old site from Rails to Elixir,
01:03
and then I've kind of documented the process on my blog as I've gone about doing that. It's not done, so I don't have a big, like, ta-da, unfortunately, but I wanted to tell you guys about the process, because I'm getting there, I'm really close to being finished. So the site that I'm porting is the old techpub.com site,
01:22
for those of you who don't know, I used to run this site, it was built on Rails, and it was all about doing videos and instructional things for people. I liked building the site, this is an interesting concept, I liked using Rails. I hated what I built. Does that make sense? I think that should be the tagline,
01:43
you know, love working in it, hate what you build. I rebuilt techpub three times, because every time I finished it, seriously, every time I got to the end, I looked back at the mountain of code that I had, the majestic monolith, as they call it, and it just was not good. I don't know, I didn't like it. Does that make sense?
02:00
You know when you look at your code and it just gives you this, anyway. So I rebuilt the site three times, it worked, it got my business up and running. This is the end of the process, this is what I have right now up on GitHub, this is my Elixir site, I called it Peach, because naming things is easy in computer science, and so I decided to call it Peach,
02:21
and the focus, I'm just going to come right out here, this is the punchline of the whole talk, the focus of this site is using Erlang and OTP, sorry, using Elixir and OTP, which is the framework underneath. When I got to this point, I loved what I wrote, and that's kind of a first for me. And I also want to say this,
02:41
that I've also gone through the whole ups and downs and ups and downs that you go through with a language or any kind of new technology, where I love it and I'm telling everybody about it, and then I get kind of frustrated and kind of bottom out, and then I get manic again, like oh my god, because I forgot all these problems, and then I come back down again, and then you kind of plane out at a certain level and you're like, you know what, I really like what I wrote, and I really like Elixir.
03:03
There's nothing on this slide, by the way. You might be wondering, what did I bring over from Rails? And so this is the punchline for that, nothing. I brought absolutely zero over, and it's an interesting concept, and that's where I'm going to start here. I started out with Phoenix.
03:20
Are you guys familiar with Phoenix? I know you are. Okay, Phoenix is the web framework that is usually the gateway that people arrive at Elixir through, if I said that right, and it's great. It's an MVC framework. It's easy to use, and so I started with it, and I thought, well, okay, I have my Rails app over here.
03:42
Phoenix is an MVC framework. Ruby and Elixir sort of look a little bit alike, so maybe this will be an easy process, and so that's why I started going through the tutorials, and I stopped at this one, and this is going to sound bad, but this is my lack of knowledge, but as I'm starting to get to know Phoenix and Elixir,
04:01
I get here to the tutorial, and I'm like, that is a scaffold. If you guys have ever used Rails, one of the big pitches about Rails is you can use the generators and the scaffold to get your site cranked out, and you end up with a structure that looks like this, and I said, oh, my God, I can't end up with another Rails site. So I'll just tell you I didn't. I stopped what I was doing,
04:21
and I did some more research, and so I'm just gonna get to the punchline on this right away, too. This is not a talk about Phoenix. That's that. It's not a talk about Ecto, which is the data framework that comes with, well, you can have in Elixir, and it's not a talk about Rails, although I'm gonna say a few things about Rails. This is a talk about OTP.
04:43
OTP is the sweetness that is underneath Elixir, underneath Erlang. It is a framework. It's the open telecom platform, is what it stands for. It's built to keep telecoms running. It's amazingly resilient. If you've gone to any of the Erlang talks, you've heard people talking about it. It's a really, really interesting way
05:02
of building programs. You have to think in terms of processes. You're gonna hear me say this again and again throughout the talk. One of the major shifts that you get into when you start working with OTP is you start seeing and thinking of code totally differently, and so that's what I'm gonna get into now. And speaking of that, I am not an expert.
05:21
My kids do my slides, by the way, and somehow this equates to me not being an expert. Don't ask me why, but I'm not an expert in Elixir. In fact, I know there's some Elixirists in the audience here. They're gonna probably look at what I'm doing, saying, I don't know about that. If there's Erlangers out there, you might be thinking I do things differently. This is about my explorations. I just wanna make that super clear.
05:41
I'm not up here to tell you this is what you need to do. This is about what I'm learning actively as I use Elixir, kind of the show you stuff. That's what I'm trying to do here. So let's take a step way back. What am I trying to do? What do I want out of this process? That's what I wanna start with. I want good data. That's what I want.
06:01
What I ended up with with TechPub and Rails was a pile of crap in my database, and I know that because when I sold TechPub later on to Pluralsight, I had to go through and generate a ton of reports, lots of customer retention information. I had Mixpanel. I had all these things running. I had Google Analytics. You'd think I'd be able to run these reports. Well, it turns out I couldn't,
06:21
and here's the really sad part. That is my background. I am a DBA. I'm a former DBA. I'm into analytics. I know these things, but using Rails, and it's my fault, but using Rails and doing things the Rails way leads you down a certain path where you just kinda don't care so much about the database, and you're gonna get to a point where you say, I'll get to that later on,
06:41
and I never did. What I ended up with was something that I wasn't too proud of. I told my daughter, make me something with a railroad that's kinda stinky, so she made me the poop train, which I think is fairly accurate. Again, I want to reiterate this. This was my fault. I can't say Rails made me do anything.
07:02
I'm a grown-up about this. At the same time, if you get into a certain mindset when you use a certain framework, it changes the way you think about the code that you're writing and what you're doing, and as developers, we go through this process, making code work for our clients and applications, and at the end of the day, you really have to believe in what you have
07:21
and the data it generates. That's the value of the application, so let's turn the corner right now, and I'll be a little bit nicer. I want to be a little bit more positive, but you need to know that what you're going to see, a lot of it, my reaction is I don't ever want to have that problem again because when I took this fictional job
07:42
at my fictional company, Red Four, I had to build this application, and I was like, okay, I'm not going to put myself in that corner again, and so I'm going to pay attention to the data. That's the thing that's important to me. When I started out here and I started doing this porting process, now let's go back and go through the process, I wanted to make sure that I had a few things.
08:01
Using Elixir, building an application, it's fun, it's a new language, it's a new way of doing things, but I needed to make sure that I have the core things that are going to make me happy and make me build a good application. Number one to me, eloquence and expressiveness. I described myself to somebody the other day as a syntax monster.
08:22
Actually, I didn't use the word monster, I used something else. Syntax in the language is incredibly important to me, and I know to other programmers it kind of sounds like a weakness. The reason I like it is because I'm not a very good programmer, and two to three years from now, when I go back and trying to figure out what I'm doing or what I did or trying to debug it,
08:41
I want to be able to read code that reads really well, and so Elixir is great for that. Speed, resilience, and I even like type safety, believe it or not, I like types. You have these things, again, in Elixir and Erlang. Working with Node and JavaScript, I would say you don't. I would say that Node is probably
09:00
the least resilient framework I've ever seen, and if you don't know what I mean, have a bug happen, and watch Node just exit the planet. It's gone, your app is offline. Now, if you go into production, you better be sure you have NodeMon running or some kind of keep-alive like PM2. Multiple processes going because, yeah, error, bye-bye.
09:21
So one of the cool things about Elixir and Erlang is the process-based stuff in OTP gets you away from that. Trustworthy framework, something like .net is amazing. I like .net, it's been around for a long time. OTP is a good counter to that as well. And then finally, a reasonable package manager, and I would say Nu-jay, I learned that word here,
09:41
Nu-jay, Nu-get, probably has its warts, let's put it that way. NPM is okay. RubyGems, I will never touch again for the rest of my life. See, I'm supposed to be positive, and there I go again. Turns out that Elixir and Erlang really, really, and I'm gonna use these together because to me at this point, and I'm just gonna get right to this,
10:01
the more I got to know Elixir and OTP, I kinda just went beneath the whole thing. I didn't care so much about Elixir anymore. The joy was building stuff in OTP, and I know I keep saying that. Let's get there. It took a mental shift to get this right, and let's go through that mental shift together because it was bonkers for me,
10:21
and for you guys, you might be thinking, well, duh, but for me, I never have thought of things this way. Let's walk through this together thinking about a shopping cart. Who here has done shopping cart code? Somebody, it's like, I think it's in Computer Science 101. When you're thinking about shopping carts, you're thinking about, well, okay, I have a cart, I have a cart item,
10:41
I have some behaviors in there, so I'm gonna start with Ruby. I know it's an Elixir talk. Let's start with Ruby. Why not? This is what you might typically see. This is semi-pseudo code. This is from the actual code I had in the Tuck Pub code base. You have a cart that's an active record, and then it has many cart items, and then you have cart item that has validations
11:02
and a bunch of other stuff on there. Seems pretty straightforward. You could do the same thing with Elixir. Now we're into Elixir. Finally, the first code slide in, what are we in, 10 minutes? All right. This is Ecto. This is Ecto code. Here we have what looks like a model. It used to be called a model.
11:21
It's not a model anymore. It's actually not important that you know that. The way this actually works is interesting. This is the first code that I started to write, because I'm thinking data first. I'm starting to bring in some data access code, thinking about my model. I lay out a cart item, and here's my schema with the fields and the database. The way that Ecto works is
11:40
it creates this thing called a change set. It's different than an active record kind of thing where you just hit record.save and it saves itself. This is a little different than it creates a thing called a change set. That change set takes in some data, reconciles it with a struct, and then you can shove it into a repository, and it just goes. You can see that code right there in add item.
12:02
It's not a real repository. This is one of the first hurdles to get over when you're working with Elixir is a lot of the naming kind of collides with what you know. In here, we're basically creating our change set, and then we're using the pipe operator. That little thing looks like a tooth and sending it into the repo, and it gets inserted.
12:21
This kind of code feels like what, do you think? It feels like the same thing to me. I know I'm probably going to get some daggers from a few people that are sitting in the audience right now, but active record is a very specific pattern. Basically, you have data in the database that gets wrapped. A row gets wrapped, and it's in your code, a one-to-one map,
12:43
and then you have some data access on top of that. That's the active record pattern. With the ectocode, what I found is it's close to the same thing. The only thing that's different is they've just taken the one part, the .save method, and moved it into another module. You can just as easily save the thing right here as part of the struct.
13:02
Again, I want to say this was my impression as I started. I have found out that things are different now, but that was my impression as I started. I decided to stop because where I was going with this is I was allowing these frameworks to dictate how I'm building my application, to dictate to me how I'm creating my data, and I don't want that.
13:22
Let's do it again now and lean on OTP, which is the underlying framework, and see if it can do something different for us. I stopped again, and I threw all my code away. I said I don't want to do that. I don't want to make the same mistake. What I want to do is to close my eyes and think about what it is I'm trying to have happen here
13:40
in a business sense. That is that a customer is browsing my products, and they're creating a sales order. That's important. As developers, we tend to think like engineers, we have a cart and a cart item, even though it doesn't make any sense at all because what we're actually doing is we're creating a sales order in the back end when a customer comes in. It's important to think like that because all of a sudden
14:02
we're starting to see things in a little bit more of a functional manner. I have a catalog that represents some data. I'm transforming that data through a process, the sales process, and what I end up with is a different set of data, which is a sales order. That's kind of a functional flow, and I locked onto something right there,
14:22
and I said that's where I'm going with this. What I did is I just scrapped everything, started again. I used Mix, which is the utility belt binary that comes with Elixir. You say Mix, New, and then the name of a project, and it spits out the project. It's incredibly handy. In this one, I used a little flag, dash, dash, S-U-P.
14:42
I want a supervision tree. I'm going to come back to what a supervision tree is, but again, I don't like holding surprises. The supervision tree is the super sweetness that goes into OTP. When you start getting that, things get really exciting, and I'm going to come back to that in just a second.
15:01
I decided I wanted to formalize what I was thinking about, transforming the catalog, going through a sales process, and then ending up with a sales order. In Elixir, in the lib directory goes your application code. I have lib, and then I have a sales directory. That's where my process is going to go. sales.ex is the process code. Inside sales, I have the catalog, which represents the data.
15:22
Simple enough. What does that catalog look like? Let's start there because you've got to have products if you're going to add them to a cart. This is my module for the catalog. It's kind of stubbed out, sitting there empty. It doesn't really do anything at this point. Wait a minute, where's the OTP? What's going on? How do we then turn this code into something that is OTP-ish?
15:44
What does it even mean? Well, now we're going to open the door on that. We now need to start thinking in terms of processes. That's the way things kind of work in the Erlang universe. You build processes that work with other processes, processes own processes or belong to other processes.
16:02
How do we take this module and turn it into a process? You might see this notation. We're going to see it again and again, the one that's right over my head in gold with the braces there. That is a process ID inside of the Erlang VM. When I say process, I'm not talking about an operating system process. I'm talking about a process that runs freely inside of the VM.
16:23
To see this, to go through this transformation, what I wanted to do is I wanted to just hard code some data because I want to start writing some tests and see stuff running in the REPL. Here I've just got a little list of two strings. If I run this code, that's where the mental shift needs to happen.
16:44
When you run code in Elixir, it always runs inside of a process. The question is, who owns that process? What happens to it? What happens if it dies? That's where we need to start. If I open up the REPL here using IEX and I say IEX-S,
17:01
it means load up my application using the script file mix.EXS. It's going to load it up, and now I have access to my module. If I type it in, as you see, peach.sales.catalog.collections, out comes my list. Big deal. Who cares? Who owns that code? Where does that come from, that module? We need to find that out, and we can.
17:21
We can use this thing in Erlang called Observer. The Observer is a really neat tool. I want the Observer to load up right now. What it's going to do is it's going to look at the VM and all the processes and applications that are running inside the VM right now. If I look in there, on the left side, you can see a list of all the currently running applications. Elixir is one of them, believe it or not. IEX, the REPL that I was just using.
17:42
Then we have Logger, and we have Mix, which is the utility thing. Then we have my little app, Peach, which is highlighted right there. Inside of Peach, you can see those little purple pills right there. Those are the processes that are currently running. If you want to know what each process is, you just double-click it. The information comes up, and at the top there is my app master loop.
18:00
That's my application actually running. The master is kind of sitting there. The next one, I actually don't have any idea what that is. Do you guys know what that is? The second process... Go back to sleep, Brian. Sorry, don't worry about it. It's only my talk. Can I get you a pillow? Do you want a blanket? Anyway, so don't ask Brian questions during your talk
18:20
if that's the takeaway here. The third one is actually the most important one. That is my supervisor. Remember that super sweet thing I told you about? That is my supervisor. That's just sitting there waiting. It's not doing anything. It's just sitting there waiting. These are the active processes that are in my application. But where's my code running? Every bit of code in Elixir runs inside of a process.
18:42
What process is running my code? This is the question that you really need to ask yourself when you start coding along and building an application out. I'll tell you why that matters in just a bit. Okay, I'll just get to the punchline here. It's running inside of IEX, which makes sense. I loaded the REPL and I said, hey, just run this module code, and it did.
19:01
So IEX is the thing that owns my module. Okay, let's switch now to a test case because we should be testing our code, right? This is what a test looks like in Elixir. I have a setup routine in there that's basically going, grabbing the data from my catalog, and then now with the return at the very bottom, whatever is returned out of setup is then passed into each test case
19:22
as the second argument. That's what you see on the second side over there. That's called a map. It's kind of like a hash. That's a long story. I won't go there. But basically what I'm doing is I'm just asserting the length of my collections is two because I hard-coded a list of two collections. So if I run this test, it works. So now what's the question we need to ask ourselves again?
19:42
What process is running my code in the test case? This is something that's going to happen a lot in your application code. And the answer is the test process owns my code. So I have no resiliency. I have no way to handle any errors that are happening here. If an error happens, things just explode, and that's bad.
20:03
Let's change that. And we change that by using this construct called a gen server. Now, I could spend an entire talk or two getting into the guts of what a gen server is, but I'll just summarize it by saying it is a formalization of creating a process that has state in OTP.
20:24
So I need to talk about that for just a second. It's actually quite interesting. Joe Armstrong that's here has a great quote. He says Erlang is the most object-oriented language there is. Erlang is a functional language, which is really funny. And the idea here is that when you're working with Erlang
20:41
in production in real code, you actually have processes that just float around in the VM, and they have to have data associated with them in the form of state. So you can actually interact with these processes, and the processes will remember what you're doing, if that makes sense. So what I want to do here with my catalog now is I want to transition my catalog into that notion.
21:02
So let's walk through this really quickly. Startlink is the first method you have to implement. What Startlink does is it talks to the gen server library, and it says, hey, there's a bunch of processes running right now in the VM. I want you to create a new one, and I want you to link it, link that running process to this module.
21:21
And this module is underscore underscore module that's in gray up there. Pass it these initial arguments, which are in the square braces right there, and then give it this name. So now we're creating a process in memory, and we're associating that process with this module, and we're giving it a name. Hooray! Init is the thing underneath it, initialize, and that just simply means that's going to be
21:42
my process's initial state. So here I'm just saying my process initial state is going to be these collections. So instead of now calling the collections method directly, I'm going to be accessing the state of this process, if that makes sense. So now if we go into collections, which is what I was calling before,
22:01
this is then going to go to gen server dot call, and that's where I'm going to wave my arms and say, we're going to get into the crazy bits of Erlang, and I'm just going to skip over that, just know that gen server's going to return the data as we expect. How does that work? Let's go back to our unit test now. I need to get access to that process. So what I'm going to do is I'm going to call start link
22:21
on my gen server now. That's going to kick up that process, and now I'll just be able to use it. So once that process is loaded in memory, I can now call my catalog collection, and if I run my tests, everything works. So this is where things get kind of tricky. We've gone and done something better. Our code is now lifted out of just being run by whatever process calls it.
22:41
It's now in its own process, but here's the next question you need to ask, who owns that process? And that's the big thing in Elixir, in Erlang in general, is processes and processes and processes and understanding these trees and understanding who owns what. So if I go back, I give it away right here. Any time you see start link, whatever process that is running in,
23:02
owns your process. So my test process still owns my catalog. So I've actually not done anything. I've just made it a little bit more difficult to read the code. Okay, now this is where we get to the fun part where I keep telling you I'm going to come back to the supervisor. This is where things get fun.
23:21
When I created my application, I created what's called a supervision tree. And a supervisor's only job in Erlang and Elixir is to restart processes that have died. And they do that all the time. Now who here has ever heard the Erlang mantra, let it crash? Anybody ever heard that before? This is fascinating. Great. This is fascinating.
23:40
You don't code defensively in Erlang. You don't have try-catch blocks. In fact, if you read the docs and it says if you use a try-catch block, that's a code smell. You should be using processes that are governed by supervisors. And the idea is if you have an error that crashes your process, the supervisor will start it again with whatever state you want. That freaked me out.
24:01
And that started getting me thinking, okay, I'm starting to get this. The rusty gear started to turn. And so I was thinking, whoa. Everything just, all these processes are owned. Like my whole thing, I just saw a Christmas tree of processes. That's my application. They're all bouncing things off of each other. And I had this ape man moment. I picked this slide specifically because,
24:23
I don't know if you've ever seen the movie 2001. In 2001, the obelisk is like, you know, the intelligence, like the shining light, like all of a sudden man is now capable of using tools, so he kills each other, which is perfect. But that's how I felt when I was starting to get down with Elixir and OTP. Okay, but I still have a problem.
24:43
I don't have it supervised yet, so I need to add this now into my application start code. So this is the startup module for my app, right? This gets called and you can see start and you can probably reason through what the start function does. It starts my app. So what I need to do is I need to create a worker.
25:00
That's what that guy is right there. I'm gonna tell it that it's going to have my catalog, and it needs to then be added to the supervision tree right there. Take a worker, I have a worker process now, I have a catalog with a bunch of state on it, it's gonna be a nice process and it's gonna now be supervised by the supervision tree in OTP.
25:22
I can make a song out of that. So now because my supervision tree is managing my catalog, what I now have is the application and the supervision tree starting it for me. So I can take that out of my setup routine. I don't have to call start link anymore. And then this just now looks like it did before.
25:41
And if I run this code, it works. But the best part is if I open up the observer again, look at that. I now have my catalog process blinking at you and then it's also in the supervision tree right there. So the supervisor now watching my catalog. Now let your mind think on that a little bit. My catalog is just gonna live in the memory of the VM
26:02
and it's gonna be full of data. And most of the time with a catalog in an e-commerce app, you don't need to hit the database. You just basically need to serve the data back. So all of a sudden you have this shift in thinking, it's like how much do I really need to work with the database? I'm gonna come back to that in just a second.
26:22
Thank you. So we still have a bit of a problem. Remember I told you I'm a syntax monster, although I used a different word. This code is not the easiest to reason through unless you know Elixir or Erlang. And you look at this code, it's really hard to figure out what I'm doing.
26:42
If you know Elixir in gen server, okay, it's fine. But we can actually reduce this. This is one of the cool things about Elixir. What we have is a long running process. You can imagine there's all kinds of different processes do all kinds of different things. There's asynchronous, there's concurrent, they live and die immediately. But ours is gonna live for a long time. So there's a construct in Elixir called an agent.
27:02
And this is an abstraction on top of Erlang's and OTP's gen server. And so now what I was able to do is to squeeze that down because what agent allows me to do, as you can see now my start link function now simply just calls agent. Agent again will then create a process for me.
27:20
But now it's taking a callback. That's what that FN arrow is. That's a callback. Just an inline function. All I need to do in this start link is to create the current state or the default state that I want in there. If there's no default state then I'm just gonna leave it. And then I give it a name. That's the end of the line down there at the bottom. Now for my collections I just need to do agent.get.
27:42
This is where things get a little bit kind of whoa, what are you talking about? Basically just know that using the agent library it's going out, grabbing a process, grabbing its state, returning it to me. I'm creating that process saying here's your data and then it's returning back to me. What would this look like in the wild? We have enough pseudo code. I kind of hard coded this. What would this actually look like in the wild?
28:02
Let's come back and use Ecto again. This is where Ecto plugs in nicely. You can see that's what I said as I started talking about Ecto. The fault basically was my own. I've changed my thinking on this now. I didn't understand what was going on before because I was thinking in terms of rails and active record models and so on. Ecto's just a data access tool and it's a brilliant one.
28:21
Am I cool? Are we cool now? Thank you. By the way, I'm going to keep pointing at him. He's one of the core committers on Phoenix and he's keeping me honest. What would we actually do here is we might just go to the database when our agent starts and grab the data that we need and then that's that. We don't have to talk to our database again.
28:40
This just stays in memory. Everybody will be thinking wait a minute. What if you update something? What if you run out of inventory? Well then you probably want to refactor this out and have a separate public model that then just reloads the state. You're going to end up actually talking to your database very rarely and you're going to let the agent handle this in memory, which is pretty cool.
29:01
Then the collections and the products by collection and then the product function down here where I started with, these are now all in memory operations. This is actual code that I have in my repo. In memory operations, super fast. What happens when my process dies? Let's say I make a query now to the collections here
29:22
and I make a query and that skews mangled and for whatever reason the database freaks out and the process dies. I have an error. Uh oh. It gets restarted. When it gets restarted, the start link comes up, bam, I have the data back and we're ready to go, which is brilliant. There are termination things I can override if I want to evaluate how is the process terminating.
29:42
I can take a look at a bad exit and all these other things. I can log stuff. I can email myself at home. That's when things really start getting fun. Okay. So let's just do a real quick review of where my little journey has taken me. Talked a little bit about the actor model. Basically an actor model is like a little,
30:01
it's a process that does something. That's an actor, essentially. I talked about processes and more processes. Supervisors keep things alive and let it crash. So with that quick review, let's jump forward. I have a semi-finished application. I want to show you what I did. It's really hard to walk through
30:21
a complex application like this, so I'm going to do my best. If you have questions, go ahead and shout them out. I'm a little tight on time, but I'll do my best to answer them for you. This is my application start code right now. And I called it store.ex. I have, in my lib directory,
30:40
I have a bunch of processes and things going on. There's a couple things I want to point out in here that I think are fascinating. On line 34 and on line 43, I'm starting two separate supervisors. And the first one is starting the sales supervisor. I'll talk about that in a second. The second one is the fulfillment supervisor.
31:00
These are going to supervise processes that I'm going to kick up. So every time, and this is fun, every time someone comes to the store, I'm actually going to create a brand new process in the VM for that person, and it's going to stay alive as the cart, basically, as the sales order. But it needs to be supervised.
31:22
So that's why I have a sales supervisor and the start sale's going to start the sales process, literally, and it's going to be supervised. So that's going to essentially be your cart. On the flip side, I also have fulfillment. So whenever you buy something, then fulfillment's going to start up a new process and fulfillment's going to do things asynchronously, and I'll get to that in a second. Let's take a look at the sales process itself.
31:42
This is actual cart code, so I called it select item instead of add item, because it's basically, I'm thinking about a customer just selecting something they want to put on the sales order. The first two function heads up there, you can think of those as overloads in C sharp. The first two functions up there handle the case when the data's in error.
32:02
So this is pattern matching in Elixir. It's one of the really fun features of the language. Something I want you to notice is I don't have a single if statement in the entire page here, and this is just a small fraction of the page. I think I have one if statement in all the code I wrote, and that's one of the more fascinating things
32:20
about using pattern matching in Elixir is you can have a combination of guard clauses, and that's what you see with the when up there, as well as pattern matching in the function arguments, and it leads you to some really clean and fun code. Okay, so with sales.ex, I'm able to then evaluate the current order
32:40
off of a thing called plug, which I'll talk about in a second, and I'm basically just evaluating, is it in the cart or is it not, and then I'm calling save change at the very end there. I'm not gonna dive too deep into the syntax here, but that's just basically the way it functions. But the big construct here, the big one is, this is the function that actually does the stuff,
33:00
which you just saw, but I just wanted to focus in on it. Notice the argument is using plug.con. And this is something that's interesting, and I've had debates about this with other Elixir folks that told me they don't think it's a very good idea to use plug, and I'll tell you what it is in just a second. But I'm using plug to take in the data that I need to then add an item to the cart,
33:22
which is the second arguments over there, skew and quantity. Plug is a really cool construct. It's part of Elixir. Not part of Elixir, I'm sorry. It's an Elixir library that you can add. If you're familiar with ASP.NET's HTTP context, you guys familiar with this? HTTP context, base, whatever.
33:41
It's basically an object, and same with Rails. You have rack passes along an object. This plug.con is web request and web response stuff. Cookies, anything that's happening in the web request is carried in this big construct called plug.con, or just con. And the front-end frameworks use it,
34:01
and there's a number of front-end web frameworks, but if you're coding in Phoenix, and you do the restful get, post, whatever, you'll be receiving an object called con, and that's plug.con, and it has a bunch of information on it. So I was able to use that directly in my API. And the reason why is I like code like this. This is a controller, if you will.
34:22
This is the Maru framework in Elixir, and it's all JSON REST response. But if you can see on line 21 there, I have post, and I'm given the con object, right? The con object comes in on every single request. Con has all the request information. It's got cookies on it and so on. So I'm able to then pipe that straight into
34:43
select item on my sales process. I have the pipe operator, and then when you use that pipe operator, the result of the previous function is the first argument and the next one. So con is passed in, and then it pops out in the back end with the order information updated and already ready to go.
35:01
So I'm able to have some really lightweight code in the web app, which I think is rad. I really like that. It keeps things really nice and clean. But let's talk about save change too. We're now back into the sales code here. I wanted to talk about data access really quickly because what you end up with is actually pretty fascinating.
35:24
If you're looking at this going, what are you doing with that data? How are you actually saving that? Down at the very bottom there on line 119, I just have one call of the database. So what's happening here with this sales process is it lives in memory for as long as it needs to. You can put a timeout on it if you want, kill it if there's no inactivity.
35:42
But it sits there, and it just receives your information back and forth, back and forth, and it essentially is growing all this data about what you're doing. I'm logging your stuff. When you're adding things, what URL you're adding them at, taking stuff away, I've said, oh, you took it away. And so I'm building this kind of big document, if you will.
36:01
So let's talk about persistence. This is the point now where I have cart functionality working. I have a process that's accreting, if you will, lots of data and information. And now I need to actually save it. But how am I gonna do that in what database? And this was my thought on that. A lot of Erlangers and Elixirists and other people
36:22
just kind of look at other programming platforms and say, you guys are really wound up about the database. In fact, you might have seen this man here giving a talk on this. I heard him say this on a podcast, and I was trying to find the link, and I couldn't. But it was just wonderful.
36:40
Far, far too much is made of the database. Now think about that in terms of what we've just been doing with supervision and all these processes running, and given the fact that the Erlang VM, provided that you don't unplug your server, the Erlang VM is known to have amazing uptime. It needs to. It powers these telecoms. Now it's not perfect. No VM's perfect. I'm not gonna make that claim.
37:01
But it tends to stay around for a really long time. So if you believe in your VM, and you've got it charted out, right, so you've got a bunch of nodes running, you have some resiliency in there that you can depend on. And I'm not kidding you when I say that there's companies out there that are actually ditching their database and going with a databaseless backend, which is crazy,
37:21
because they're listening to this man too much. That's Joe Armstrong. He's the creator of Erlang along with Robert Verding. They're both here. I don't think along those terms. I'm too much of a wacko. I need to make sure I've got good persistence. So I want to now go into the decisions that I can make. It just so happens that you... Uh-oh. Did you guys finally elbow that guy off the side?
37:41
Yeah. I was gonna say, this is really bothering me up there. Could someone throw them off the side? Anyway. I have three choices. I have an in-memory data store that I can use in the VMs. The VM just says, Sure, I'll hold your data for you. So if my process crashes, so let's say your sales order that you're building in memory
38:00
and your little process is running dies for some reason. That data's gone. So now we need to get that data back. So what we can do is we can store it in this thing called Erlang Term Store, or ETS. And it's just an in-memory, atomic, isolated, da-da-da-da. And it's pretty neat. And it'll load up your data again. So that's interesting. The problem is the server comes unplugged,
38:20
you lose the data, but at that point you gotta think to yourself, How often is the server gonna get unplugged and how often am I gonna restart it without making sure that I shut everything down beforehand and so on? So now data persistence is starting to seem, Oh gosh, who cares? I don't know. I mean, right? Am I crazy? I am a little crazy. The second choice I have is disk storage debts.
38:41
So you can store this stuff to disk. It's not quite as fast, but if you guys want to, you can. The third option is really trippy. It's a NoSQL database built into Erlang, which I think is nuts. It's called Amnesia. Wasn't that a great name? Amnesia? I don't know. So Amnesia is built in, and a lot of people use it, but it's not designed to take over SQL storage.
39:03
So they kind of tell you it's great for things like a cart, for instance. If it's just this transitional data that you're gonna write at some point later on, which makes me think, given all of this, when do I really, really need to write the data to the database?
39:21
That's fascinating to me. I mean, before with Rails app, I would say, Okay, you're gonna add an item to cart. Well, that's going to the database, right? Because if something crashes, at least I have your data. So everything, I have all these bam, bam, bam, bam, things going on in the database, writing the database. Well, now I'm at the point where I need to validate what I've been doing. Remember, I told you my whole focus has been
39:41
making sure I have the right data. I don't want to have this tech pub mess that I had before. So now I know I have a bunch of data, but when do I actually need to write it to the database? What I came up with is, Well, I really probably only need to write it if you guys agree to buy something, and then I'll drop it down to the database and we'll be done.
40:01
But I'm a little more paranoid than that, so I decided to do it on every single time. Anything has changed in the state of your session, or your sale, I should say. So that's what I call save change. But this is great. What do we end up with? So you come in, you buy something, all your cart stuff is in there, all the logs that you've got,
40:21
all the items you want to buy. You've bought something, so I've got payment response from the gateway. I've also got all your checkout information. This is great. This is the document that gets saved to the database. It is gigantic. And you've got to think,
40:41
either that you're absolutely out of your mind when you write something like this to the database, or if you're like me, you're thinking this is gold. And I'll tell you why, is because I said before, I actually lost money when Pluralsight came along, and I couldn't give them these reports that demonstrated the value of my company. So I couldn't say,
41:01
No, you're going to pay me twice that, because look at my churn rate. If I could just take all the data from everything you've just done to buy something from me, every bit of it, it's a gold mine. I just capture the result of that process, shove it in the database, and now what I have is ch-ching. I have data that I can then use later in reports,
41:20
which I think is absolutely wonderful. And I'll just tell you right now, if I had that amount of data in there, I'd be so excited. Now let's just really quickly touch on that. That is a massive blob of a JSON document. That's going into a Postgres database, JSONB store. It can go into anything you want. Are we going to actively use that in our application and actively query it?
41:41
Hell no. Not a chance. That is a historical document that sits in there. Now if I want to do other things with that data, say I want to do some kind of invoice creation, I want to do some mailers, I want to do some logging, I want to do other things. Well, that's out of process stuff, isn't it? I go and scrape that document now
42:01
with my brand new fulfillment process that just got kicked up asynchronously, completely out of band, and it's doing all the things that I need to have happen after an order happens. So it's just a record that's sitting there. Your sales process has gone away by now. I've killed it. It's out of the VM. You've checked out. I've said thank you. It's literally instantaneous.
42:21
And all your stuff is written down. I'm kicking up my new fulfillment process here, which again is using agent. But this time we're doing something a little bit different. So this agent code is going to use agent.cast. That's an asynchronous call. And so cast means fire and forget. And so what I want to have happen is
42:41
I want to have a series of operations that go off. And it depends on your business and what you want to do. But here, let's just walk through them really quickly. I want to provision your order, whatever, and get it together because I'm going to deliver it to you. Then I want to prepare the mailers. That's the next one down the middle line there. I need to send out some emails, capture the actual sales, so talk to Stripe or PayPal
43:01
to actually send out some code and capture that sale. Why do that in line? If it fails, then yeah, you can send that person an email and say, hey, you know, your card failed. I'd love to send you the thing you just bought. Can you come back and give me a better card? That's something you can do. To execute all of this, I'm using a with block. So basically this is one of the new constructs in Elixir.
43:21
And it basically says execute all these things. If any one of these steps fails, give me back an error and tell me what happened. And then what I can do is if after everything completes, if it does complete, I'm using pattern matching again here. If it completes with an error, then I just tick the order status to unfulfilled. You see it in your admin screen as unfulfilled and you can go change it and fix it.
43:42
Now think about that. What if you guys tried to send mailers and do all this stuff when a person hits buy and you're trying to send mailers and let's say, for instance, Mandrel decides to not work anymore like it happened to me. And it dies. So that order process, should that order process die?
44:02
No. But if you write your code synchronously like that in a chain, like okay, we're gonna capture the card, we're gonna send a mailer, and the mailer dies, you're in trouble. So here I'm allowing for the admin to come in and fix whatever went wrong. So Mandrel might have died. Let's go fix Mandrel and then okay, try and send those mailers again. That's what we can do here.
44:20
Otherwise, I'm gonna go down and then save the order to the database and we're good to go. Okay. Again, this is what I have created. It's up on GitHub right now. It is not done. I wish it was. I wish I could say ta-da, but I can't. The one thing I just want to point out to you guys,
44:42
and this was supposed to be on my punchline, is I haven't talked at all about the web framework. And that to me is glorious. And it's not because I dislike the web framework or anything. I will be using Phoenix. But the web framework has nothing to do with my application. It didn't guide me into doing things a certain way, putting things in a certain folder, and so on.
45:01
I actually built an application that I absolutely love, that has resiliency and has an amazing data access story, and it makes me very happy. So I guess that's the big thing. That's it. So that's what you can build with Elixir, and to me that is the story of Elixir is actually OTP. And a lot of people agree with me on that.
45:21
They think, wow, Elixir syntax is amazing. I'm not taking anything away from that, nor am I trying to take anything away from Phoenix, but everything underneath it is just gold. So I'm going to end it now, but if you guys have any questions, please do shout them out. That's it. Thank you.
45:46
Except for you guys. Anybody have questions? Yeah. The question is, is there an idea of primary and secondary replicas in Erlang?
46:00
That gets a little bit beyond what I know. I might deflect to Brian Hunter, who's sitting over here. I know that you can have what are called nodes, multiple VMs linked together, and they're supposed to work in tandem, but does that get that right? Okay.
46:33
Yep. Okay. Anybody else? I can't even see you guys. I guess you don't. Okay. Thank you very much.
46:40
Appreciate it.