Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ In this last chapter, we will go back to the `:kv` application and add a routing
The routing layer will receive a routing table of the following format:

```elixir
[{?a..?m, :"foo@computer-name"},
{?n..?z, :"bar@computer-name"}]
[
{?a..?m, :"foo@computer-name"},
{?n..?z, :"bar@computer-name"}
]
```

The router will check the first byte of the bucket name against the table and dispatch to the appropriate node based on that. For example, a bucket starting with the letter "a" (`?a` represents the Unicode codepoint of the letter "a") will be dispatched to node `foo@computer-name`.
Expand Down Expand Up @@ -195,8 +197,7 @@ defmodule KV.Router do
"""
def table do
# Replace computer-name with your local machine name.
[{?a..?m, :"foo@computer-name"},
{?n..?z, :"bar@computer-name"}]
[{?a..?m, :"foo@computer-name"}, {?n..?z, :"bar@computer-name"}]
end
end
```
Expand Down Expand Up @@ -296,9 +297,11 @@ Open up `apps/kv/mix.exs` and change the `application/0` function to return the

```elixir
def application do
[extra_applications: [:logger],
env: [routing_table: []],
mod: {KV, []}]
[
extra_applications: [:logger],
env: [routing_table: []],
mod: {KV, []}
]
end
```

Expand Down Expand Up @@ -336,9 +339,7 @@ This means we can also configure our `:routing_table` directly in the `apps/kv/c

```elixir
# Replace computer-name with your local machine nodes.
config :kv, :routing_table,
[{?a..?m, :"foo@computer-name"},
{?n..?z, :"bar@computer-name"}]
config :kv, :routing_table, [{?a..?m, :"foo@computer-name"}, {?n..?z, :"bar@computer-name"}]
```

Restart the nodes and run distributed tests again. Now they should all pass.
Expand Down
22 changes: 11 additions & 11 deletions getting-started/mix-otp/docs-tests-and-with.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ defmodule KVServer.Command do

## Examples

iex> KVServer.Command.parse "CREATE shopping\r\n"
iex> KVServer.Command.parse("CREATE shopping\r\n")
{:ok, {:create, "shopping"}}

"""
Expand Down Expand Up @@ -148,19 +148,19 @@ Notice how we were able to elegantly parse the commands without adding a bunch o
Finally, you may have observed that each doctest was considered to be a different test in our test case, as our test suite now reports a total of 7 tests. That is because ExUnit considers the following to define two different tests:

```iex
iex> KVServer.Command.parse "UNKNOWN shopping eggs\r\n"
iex> KVServer.Command.parse("UNKNOWN shopping eggs\r\n")
{:error, :unknown_command}

iex> KVServer.Command.parse "GET shopping\r\n"
iex> KVServer.Command.parse("GET shopping\r\n")
{:error, :unknown_command}
```

Without new lines, as seen below, ExUnit compiles it into a single test:

```iex
iex> KVServer.Command.parse "UNKNOWN shopping eggs\r\n"
iex> KVServer.Command.parse("UNKNOWN shopping eggs\r\n")
{:error, :unknown_command}
iex> KVServer.Command.parse "GET shopping\r\n"
iex> KVServer.Command.parse("GET shopping\r\n")
{:error, :unknown_command}
```

Expand Down Expand Up @@ -301,24 +301,24 @@ def run({:create, bucket}) do
end

def run({:get, bucket, key}) do
lookup bucket, fn pid ->
lookup(bucket, fn pid ->
value = KV.Bucket.get(pid, key)
{:ok, "#{value}\r\nOK\r\n"}
end
end)
end

def run({:put, bucket, key, value}) do
lookup bucket, fn pid ->
lookup(bucket, fn pid ->
KV.Bucket.put(pid, key, value)
{:ok, "OK\r\n"}
end
end)
end

def run({:delete, bucket, key}) do
lookup bucket, fn pid ->
lookup(bucket, fn pid ->
KV.Bucket.delete(pid, key)
{:ok, "OK\r\n"}
end
end)
end

defp lookup(bucket, callback) do
Expand Down
2 changes: 1 addition & 1 deletion getting-started/mix-otp/dynamic-supervisor.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ In the Applications tab, you will see all applications currently running in your
Not only that, as you create new buckets on the terminal, you should see new processes spawned in the supervision tree shown in Observer:

```iex
iex> KV.Registry.create KV.Registry, "shopping"
iex> KV.Registry.create(KV.Registry, "shopping")
:ok
```

Expand Down
2 changes: 1 addition & 1 deletion getting-started/mix-otp/genserver.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ Let's reimplement the server callbacks to fix the bug and make the test pass. Fi

def init(:ok) do
names = %{}
refs = %{}
refs = %{}
{:ok, {names, refs}}
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ We can also configure the generated `.app` file by customizing the values return

### Starting applications

When we define a `.app` file, which is the application specification, we are able to start and stop the application as a whole. We haven't worried about this so far for two reasons:
When we define an `.app` file, which is the application specification, we are able to start and stop the application as a whole. We haven't worried about this so far for two reasons:

1. Mix automatically starts our current application for us

Expand Down
6 changes: 3 additions & 3 deletions getting-started/mix-otp/task-and-gen-tcp.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ defmodule KVServer do
# 3. `active: false` - blocks on `:gen_tcp.recv/2` until data is available
# 4. `reuseaddr: true` - allows us to reuse the address if the listener crashes
#
{:ok, socket} = :gen_tcp.listen(port,
[:binary, packet: :line, active: false, reuseaddr: true])
Logger.info "Accepting connections on port #{port}"
{:ok, socket} =
:gen_tcp.listen(port, [:binary, packet: :line, active: false, reuseaddr: true])
Logger.info("Accepting connections on port #{port}")
loop_acceptor(socket)
end

Expand Down