I've been playing with Elixir a bit lately, and it's incredibly attractive for a lot of reasons that I won't get into here. I learn faster when others peruse my code, and I like sharing what I've learned as I go along... Sooooo, let's build something!
Create a New Project
I'm going to call my awesome new world-changing time series database "StatsYard". We'll use mix to get kicked off:
This lays down the bones we need to start building stuff. (Note: Even though we named our project "stats_yard", the actual namespace will be StatsYard as shown below.
I like to name my files the same as the module they contain wherever possible, but it isn't required - I just find it eases troubleshooting. The convention I've seen everywhere else is to name your Elixir files after the modules they contain, but in all lower case and with words separated by an underscore ( _ ). Now let's define our module StatsYard.TimestampWriter:
Not too much special here if you're generally familiar with GenServer:
Oops. We must have missed something - GenServer.do_send/2 is unhappy with our arguments. This particular function accepts two arguments: the Process ID (PID) of the GenServer whose callback you're trying to invoke, and the body of the message you want to send. In our case, our public write_timestamp/2 function is actually not calling a private function in our GenServer, but is instead sending a message to the GenServer's PID. That message contains a tuple that the GenServer should pattern match appropriately upon receipt.
So, where did we go wrong? The message payload ( {:write_timestamp, "/tmp/foo.tstamp", 1459134853371}} ) certainly looks correct, so it seems to be the first argument, the GenServer's PID.
When you name a GenServer you're effectively mapping an atom to a PID, which allows you to reference the process without having to know it's PID in advance. In our case, __MODULE__ equates to :"StatsYard.TimestampWriter", which should then map to our PID.... Oh, right! We don't have a PID, because we never started our GenServer process. Easy fix!
Now we just need to check our output file and make sure it actually did what it was supposed to:
Success!
Define Our GenServer
Let's create a GenServer that writes the current timestamp plus some message to a file upon request.
Mosey on over to stats_yard/lib and create a new directory with the same name as our project, stats_yard. Within that directory, create a file named timestamp_writer.ex :
Crack that bad boy open and let's build a GenServer!
Not too much special here if you're generally familiar with GenServer:
- Line 8: A public function to make it easier to invoke the GenServer's callbacks
- Line 12: start_link is the function we'll use to startup our process running the GenServer
- Line 20: init is called by start_link and is the way we set the initial state of our GenServer (for now, just the integer 0)
- Line 24: Our cast callback for actually doing the work. We could have made the timestamp a value that's calculated every time we cast to the GenServer, but for the sake of a TSDB we'll want to be able to accept arbitrary timestamps, not solely "right now" timestamps
Let's see if it works! From the top level of our project, we'll hop into iex:
Now let's run the appropriate commands and hopefully we'll see a timestamp written to the file we specify:
Oops. We must have missed something - GenServer.do_send/2 is unhappy with our arguments. This particular function accepts two arguments: the Process ID (PID) of the GenServer whose callback you're trying to invoke, and the body of the message you want to send. In our case, our public write_timestamp/2 function is actually not calling a private function in our GenServer, but is instead sending a message to the GenServer's PID. That message contains a tuple that the GenServer should pattern match appropriately upon receipt.
So, where did we go wrong? The message payload ( {:write_timestamp, "/tmp/foo.tstamp", 1459134853371}} ) certainly looks correct, so it seems to be the first argument, the GenServer's PID.
When you name a GenServer you're effectively mapping an atom to a PID, which allows you to reference the process without having to know it's PID in advance. In our case, __MODULE__ equates to :"StatsYard.TimestampWriter", which should then map to our PID.... Oh, right! We don't have a PID, because we never started our GenServer process. Easy fix!
Now we just need to check our output file and make sure it actually did what it was supposed to:
Success!
Next Time
That's it for now, nothing too interesting just yet. Next time we'll see what happens when our GenServer dies, and what we can do about that.
For now, you can peruse the source for this post at: https://github.com/strofcon/stats-yard/tree/lets-build-1
For now, you can peruse the source for this post at: https://github.com/strofcon/stats-yard/tree/lets-build-1
One nameless on line casino worker recollects that the Pelayos started to win big at the time that staff were engaged in a dispute with their bosses. Initially, Gonzalo wished to understand how croupiers placed balls initially of every roulette spin. Wondering whether this motion may be the key thing} to determining the ultimate end result of every spherical. DisclaimerAll content on this website, including dictionary, thesaurus, literature, geography, and other reference knowledge is for informational purposes solely. This info should not be thought-about full, updated, and is not supposed for use instead of a go to, session, or advice of a legal, medical, or some other skilled. Where an automated Roulette wheel is used discover out} the 점보카지노 outcome result} of the game the ball shall be spun automatically by the automated Roulette wheel in a path reverse to the rotation of the wheel.
ReplyDelete