From 0d5feff4578cf417a730579458fc840689d4e762 Mon Sep 17 00:00:00 2001 From: Konrad Zemek Date: Thu, 12 Jul 2018 13:37:21 +0200 Subject: [PATCH] Add repro for bitwalker/swarm#91 --- Dockerfile | 6 ++++++ README.md | 13 +++++++++++++ docker-compose.yml | 5 +++++ lib/my_app.ex | 26 ++++++++++++++++++++++++++ mix.exs | 29 +++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 lib/my_app.ex create mode 100644 mix.exs diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0b56c2c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM elixir:1.6.6-alpine + +RUN mkdir /app +WORKDIR /app +COPY . . +RUN mix do local.hex --force, deps.get, compile diff --git a/README.md b/README.md new file mode 100644 index 0000000..5aedd9c --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +### Swarm deadlock repro + +This repository serves as a repro for bitwalker/swarm#91 . +To start reproducing, simply run: + +```sh +docker-compose up --scale repro=5 +``` + +This command will build a docker image with the compiled repro Elixir application, +and run 5 instances of the image. All the application does is start `Swarm` and + `Libcluster` with `Cluster.Strategy.Gossip` topology. A single process on each +node prints state of the local `Swarm.Tracker` process. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1e4cfdf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,5 @@ +version: '2' +services: + repro: + build: . + command: ['sh', '-c', 'iex --cookie mycookie --name "node@$$(hostname -i)" -S mix'] diff --git a/lib/my_app.ex b/lib/my_app.ex new file mode 100644 index 0000000..88e18dc --- /dev/null +++ b/lib/my_app.ex @@ -0,0 +1,26 @@ +defmodule TrackerStateMonitor do + use Task, restart: :permanent + + def start_link(_args) do + Task.start_link(fn -> + Stream.repeatedly(fn -> Process.sleep(5000) end) + |> Enum.each(fn _ -> + {state, _} = :sys.get_state(Swarm.Tracker) + IO.puts("Swarm.Tracker state: #{state}") + end) + end) + end +end + +defmodule MyApp do + use Application + + @impl Application + def start(_type, _args) do + Supervisor.start_link([ + {Cluster.Supervisor, + [[local: [strategy: Cluster.Strategy.Gossip]], [name: MyApp.ClusterSupervisor]]}, + {TrackerStateMonitor, []} + ], strategy: :one_for_one) + end +end diff --git a/mix.exs b/mix.exs new file mode 100644 index 0000000..0bdacf5 --- /dev/null +++ b/mix.exs @@ -0,0 +1,29 @@ +defmodule MyApp.MixProject do + use Mix.Project + + def project do + [ + app: :my_app, + version: "0.1.0", + elixir: "~> 1.6", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger, :sasl], + mod: {MyApp, []} + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:libcluster, "~> 3.0"}, + {:swarm, "~> 3.3"} + ] + end +end