Skip to content

Instantly share code, notes, and snippets.

@rozap
Created October 8, 2016 00:03
Show Gist options
  • Save rozap/247e8cfce79d86f86d9dc200041ed022 to your computer and use it in GitHub Desktop.
Save rozap/247e8cfce79d86f86d9dc200041ed022 to your computer and use it in GitHub Desktop.

~~elixirpalooza~~

Installing

Run brew install elixir

Learning

I'm not going to be able to do a better job giving an overview of the language than what's already documented here:

http://elixir-lang.org/getting-started/introduction.html

The Pattern Matching and Processes sections are probably the most interesting, as they're the things that are different from other languages.

Do not be scared, as "it's all just computer code" - some concepts may seem alien at first, but there are not too many concepts to learn.

If you have questions, please please slack message me

This is boring, I want to see something cool.

Here's a super quick intro to distributed erlang/elixir. Assuming you read the Processes section in the guides I linked aboved, this should make sense at a high level.

From the VM's perspective, 2 nodes running on the same host or 1 node running on 2 hosts, is still just two nodes. So we can do distributed erlang with just one host, by starting 2 repls's.

Start a repl, we'll call this node hello

In a terminal session, write

iex --name hello@127.0.0.1 --cookie monster

So now you have a repl running. Nodes are identified by their name and address, --name tells the node that info. A cookie is a shared value that all nodes must have in order to join the cluster. It allows you to run multiple, separate clusters on the same network. Our cookie's value for our cluster will be monster

Now, in a new terminal session, note the different name, same cookie

iex --name world@127.0.0.1 --cookie monster

Now that you have two nodes running, we will connect them

In the "world" node, you can run the Node.connect/1 function, which joins nodes together, and returns true if it succeeds. (Note that we're in the repl now - if you're copying pasting along, you would only copy the Node.connect(:'hello@127.0.0.1') function call bit)

iex(world@127.0.0.1)1> Node.connect(:'hello@127.0.0.1')
true

Now in the hello repl, we'll spawn a process, and it will block until it receives a message. If it receives a {:remote_execute, func} message, it will execute the function.

iex(hello@127.0.0.1)1> pid = spawn_link(fn ->
...(hello@127.0.0.1)1>   receive do
...(hello@127.0.0.1)1>     {:remote_execute, some_func} -> some_func.()
...(hello@127.0.0.1)1>     other -> IO.puts "Received a strange message #{inspect other}"
...(hello@127.0.0.1)1>   end
...(hello@127.0.0.1)1> end)

Now we'll make a process group called :servers, and put our new process in that group.

iex(hello@127.0.0.1)2> :pg2.create(:servers)
iex(hello@127.0.0.1)3> :pg2.join(:servers, pid)

Head over to your other repl, world

We'll look up all the processes that have joined our :servers group. We know there's only one in there, so we can pattern match against a list of length 1.

iex(world@127.0.0.1)2> [pid] = :pg2.get_members(:servers)

Finally, we'll send that process a message.

iex(world@127.0.0.1)3> send pid, {:remote_execute, fn -> IO.puts "Hello, Hello!" end}

Now look at the hello node. You'll see that it printed "Hello, Hello" to the console.

So in a couple lines of code, you made a cluster which can send functions that execute anywhere else in the cluster. Are you not entertained?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment