Skip to content

Commit

Permalink
first steps to writing a distributed water cooler application
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Jun 12, 2017
1 parent a3fb5b1 commit 23d9f66
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 23 deletions.
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM elixir:1.4.4

# Important! Update this no-op ENV variable when this Dockerfile
# is updated with the current date. It will force refresh of all
# of the base images and things like `apt-get update` won't be using
# old cached versions when the Dockerfile is built.
ENV REFRESHED_AT=2017-06-02

RUN apt-get update && apt-get install -y inotify-tools

RUN mix local.hex --force && mix local.rebar --force

COPY mix.* /app/
COPY config /app/config
RUN cd /app && mix deps.get && mix deps.compile

COPY . /app

WORKDIR /app

CMD iex -S mix
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ Example chat application built with [Tokumei](https://hex.pm/packages/tokumei).

```
cd water_cooler
mix deps.get
iex -S mix
docker-compose up
docker-compose scale web=3
```

Visit http://localhost:8080

```
for i in `docker ps -q`; do echo $i; echo " : "; docker inspect $i | grep -i ipaddress | grep -v null | cut -d ':' -f 2; done
```


## Run tests


```
mix test
docker run web mix test
```

## TODO
Expand Down
1 change: 1 addition & 0 deletions debug.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
iex --name debug@$(hostname -I) --cookie $ERLANG_COOKIE
24 changes: 10 additions & 14 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
version: '2'

services:
water_cooler:
image: "water_cooler:release"
web:
build:
context: "."
dockerfile: "Dockerfile"
environment:
- PORT=8080
command: "foreground"
ports:
- "8080:8080"
- "8443:8443"
water_cooler_build:
image: "water_cooler:build"
environment:
- PORT=8080
command: "mix run --no-halt"
ports:
- "8081:8080"
- "8444:8443"
- SECURE_PORT=8443
- SERVICE_NAME=web
- ERLANG_COOKIE=asd&%rewss
volumes:
- .:/app
command: sh start.sh
3 changes: 2 additions & 1 deletion lib/water_cooler/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule WaterCooler.Application do

children = [
worker(WaterCooler.WWW, [[port: port()]], id: :http),
worker(WaterCooler.WWW, [[port: secure_port(), tls: tls_options]], id: :https)
worker(WaterCooler.WWW, [[port: secure_port(), tls: tls_options]], id: :https),
worker(WaterCooler.DNSDiscovery, [System.get_env("SERVICE_NAME")])
]

opts = [strategy: :one_for_one, name: WaterCooler.Supervisor]
Expand Down
4 changes: 2 additions & 2 deletions lib/water_cooler/chat_room.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ defmodule WaterCooler.ChatRoom do
end

def publish(message, room \\ @default_room) do
:gproc.send({:p, :l, room}, post(message))
:gproc.send({:p, :g, room}, post(message))
{:ok, message}
end

def join(room \\ @default_room) do
:gproc.reg({:p, :l, room})
:gproc.reg({:p, :g, room})
{:ok, room}
end
end
27 changes: 27 additions & 0 deletions lib/water_cooler/dns_discovery.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule WaterCooler.DNSDiscovery do
use GenServer

@connect_interval 5_000 # try to connect every 5 seconds

def start_link(hostname, opts \\ []) do
hostname = to_charlist(hostname)
GenServer.start_link(__MODULE__, hostname, opts)
end

def init(state) do
send(self(), :refresh)
{:ok, state}
end

def handle_info(:refresh, hostname) do
ip_addresses = :inet_res.lookup(hostname, :in, :a)
for {a, b, c, d} <- ip_addresses do
Node.connect :"#{hostname}@#{a}.#{b}.#{c}.#{d}"
end

IO.puts "Nodes: #{inspect Node.list}"
# IO.puts(Node.list |> length |> to_string)
Process.send_after(self(), :refresh, @connect_interval)
{:noreply, hostname}
end
end
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ defmodule WaterCooler.Mixfile do
{:server_sent_event, "~> 0.1.0"},
{:gproc, "0.3.1"},
{:mix_docker, "~> 0.4.2"},
{:exsync, "~> 0.1.4"}
{:exsync, "~> 0.1.4"},
{:wobserver, "~> 0.1.7"}
]
end
end
16 changes: 15 additions & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
%{"ace": {:hex, :ace, "0.9.0", "c7255dea811db3ec8b4d461c852f746896de800aba94d3a3afaa0e165edc34e7", [:mix], [], "hexpm"},
"ace_http": {:hex, :ace_http, "0.4.5", "3227ec8407f7eecbeeb9026b854c07b28c4f6b2f9617d99d1997788a8c962b46", [:mix], [{:ace, "~> 0.9.0", [hex: :ace, repo: "hexpm", optional: false]}, {:http_status, "~> 0.2.0", [hex: :http_status, repo: "hexpm", optional: false]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
"distillery": {:hex, :distillery, "1.4.0", "d633cd322c8efa0428082b00b7f902daf8caa166d45f9022bbc19a896d2e1e56", [:mix], [], "hexpm"},
"exfswatch": {:hex, :exfswatch, "0.4.2", "d88a63b5c2f8f040230d22010588ff73286fd1aef32564115afa3051eaa4391d", [:mix], [], "hexpm"},
"exsync": {:hex, :exsync, "0.1.4", "f5800f5c3137271bf7c0f5ca623919434f91798e1be1b9d50fc2c59168d44f17", [:mix], [{:exfswatch, "~> 0.4", [hex: :exfswatch, repo: "hexpm", optional: false]}], "hexpm"},
"gproc": {:hex, :gproc, "0.3.1", "ec14f40cb941bde3f940de59c11e59beb2977e90dbae72fab3ddf77743fd4ea9", [:rebar], [], "hexpm"},
"hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"http_status": {:hex, :http_status, "0.2.1", "74fa942b5874966a25088162e5297ad52dd5e6a29b88ad4a73953aa55e58e3bb", [:mix], [], "hexpm"},
"httpoison": {:hex, :httpoison, "0.11.2", "9e59f17a473ef6948f63c51db07320477bad8ba88cf1df60a3eee01150306665", [:mix], [{:hackney, "~> 1.8.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"mix_docker": {:hex, :mix_docker, "0.4.2", "366b99bf6091155f40d408db5d8509a8760fd669442eeacdcf8444effc9f04d6", [:mix], [{:distillery, "~> 1.2", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
"raxx": {:hex, :raxx, "0.11.1", "9e2e8955fae9ecd33dc0a6d9cd50d083b209f3c859c548db0197ce39b9247146", [:mix], [{:http_status, "~> 0.2", [hex: :http_status, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"raxx_cookie": {:hex, :raxx_cookie, "0.1.0", "caa7304180dcedfc166d28648c3a1baa142d89e2aa9a5406616f76686a8bedb7", [:mix], [], "hexpm"},
"raxx_static": {:hex, :raxx_static, "0.3.0", "1c49edf960227e7125a388355fcc8a2419fea52d6f36cc6cc09d9efb854b0a87", [:mix], [{:raxx, "~> 0.11.0", [hex: :raxx, repo: "hexpm", optional: false]}], "hexpm"},
"server_sent_event": {:hex, :server_sent_event, "0.1.0", "bdc746a63ac5b8c2dbeb6235fd91b4dd662ce9c92e8547c58c2a0e3a647f551b", [:mix], [], "hexpm"},
"tokumei": {:hex, :tokumei, "0.6.3", "edf6c03229d59e88271079b92945fd4166fa5c1926220f1136ec054bd051a47c", [:mix], [{:ace_http, "~> 0.4.5", [hex: :ace_http, repo: "hexpm", optional: true]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}, {:raxx_cookie, "~> 0.1.0", [hex: :raxx_cookie, repo: "hexpm", optional: false]}, {:raxx_static, "~> 0.3.0", [hex: :raxx_static, repo: "hexpm", optional: false]}], "hexpm"}}
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"tokumei": {:hex, :tokumei, "0.6.3", "edf6c03229d59e88271079b92945fd4166fa5c1926220f1136ec054bd051a47c", [:mix], [{:ace_http, "~> 0.4.5", [hex: :ace_http, repo: "hexpm", optional: true]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}, {:raxx_cookie, "~> 0.1.0", [hex: :raxx_cookie, repo: "hexpm", optional: false]}, {:raxx_static, "~> 0.3.0", [hex: :raxx_static, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"},
"websocket_client": {:hex, :websocket_client, "1.2.1", "a965ce0be5583c90347400bceca66629e4debd5feb9bd516107e2924bdf39dad", [:rebar3], [], "hexpm"},
"wobserver": {:hex, :wobserver, "0.1.7", "377b9a2903728b62e4e89d4e200ec17d60669ccdd3ed72b23a2ab3a2c079694d", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, repo: "hexpm", optional: false]}, {:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:websocket_client, "~> 1.2", [hex: :websocket_client, repo: "hexpm", optional: false]}], "hexpm"}}
10 changes: 10 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# NOTE dependencies should be fetched before this step,
# so they are committed to mix.lock.
set -e

mix deps.get

echo $(hostname -I)
echo $SERVICE_NAME
echo $ERLANG_COOKIE
elixir --name $SERVICE_NAME@$(hostname -I) --cookie $ERLANG_COOKIE -S mix run --no-halt

0 comments on commit 23d9f66

Please sign in to comment.