Skip to content

fix: Change example approach to use Docker Compose #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM elixir as builder

RUN apt-get update -y \
&& apt-get install -y build-essential git \
&& apt-get clean

ENV MIX_ENV=prod

RUN mix local.hex --force && mix local.rebar --force
ADD ../../ /app

WORKDIR /app
RUN mix compile

WORKDIR /app/example
RUN mix release
CMD [ "_build/prod/rel/example/bin/example", "start", "--sname", "service", "--no-halt" ]
47 changes: 35 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,28 @@

Postgres Strategy for [libcluster](https://hexdocs.pm/libcluster/) which is used by Supabase on the [realtime](https://github.com/supabase/realtime) and [supavisor](https://github.com/supabase/supavisor) projects.

It uses Postgres `LISTEN` and `NOTIFICATION` to send the information from a given node and connects them using libcluster.
You can test it out by running `docker compose up`

![example.png](example.png)

## Installation

The package can be installed
by adding `libcluster_postgres` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:libcluster_postgres, "~> 0.1"}]
end
```

## How it works

We connect to a Postgres instance using Postgrex. With the [Postgrex.Notifications](https://hexdocs.pm/postgrex/Postgrex.Notifications.html) module we will track for `LISTEN` events on the configured channel. We'll also use `NOTIFY` queries to send the node's information.

## How to use it

To use it, set your configuration file with the informations for your database:

```elixir
config :libcluster,
Expand All @@ -22,17 +42,20 @@ config :libcluster,
]
]
```

To see it in use run the script `./test.sh` in this folder and you will see that both nodes connected as expected and are able to list one another.


## Installation

The package can be installed
by adding `libcluster_postgres` to your list of dependencies in `mix.exs`:
Then add it to your supervision tree:

```elixir
def deps do
[{:libcluster_postgres, "~> 0.1"}]
defmodule MyApp do
use Application

def start(_type, _args) do
topologies = Application.get_env(:libcluster, :topologies)
children = [
# ...
{Cluster.Supervisor, [topologies]}
# ...
]
Supervisor.start_link(children, strategy: :one_for_one)
end
end
```
```
14 changes: 13 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
version: "3.8"

services:
postgres:
db:
image: postgres:latest
ports:
- 5432:5432
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
service1:
depends_on:
- db
build: .
service2:
depends_on:
- db
build: .
service3:
depends_on:
- db
build: .
Binary file added example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions example/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
26 changes: 26 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
example-*.tar

# Temporary files, for example, from tests.
/tmp/
21 changes: 21 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Example

**TODO: Add description**

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `example` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:example, "~> 0.1.0"}
]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/example>.

19 changes: 19 additions & 0 deletions example/config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Config

config :logger, :console,
format: "[$level[node:$node] $message\n", metadata: [:node]

config :libcluster, topologies: [
postgres: [
strategy: Cluster.Strategy.Postgres,
config: [
hostname: "db",
username: "postgres",
password: "postgres",
database: "postgres",
port: 5432,
parameters: [],
channel_name: "cluster"
]
]
]
8 changes: 8 additions & 0 deletions example/lib/example.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Example do
use Application
def start(_type, _args) do
topologies = Application.get_env(:libcluster, :topologies)
children = [{Cluster.Supervisor, [topologies]}, NodeCheck]
Supervisor.start_link(children, strategy: :one_for_one)
end
end
16 changes: 16 additions & 0 deletions example/lib/node_check.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule NodeCheck do
use GenServer
require Logger
def start_link(_), do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
def init(_) do
Process.send_after(self(), :check, 1_000)
{:ok, []}
end

def handle_info(:check, state) do
Logger.info("Connected nodes: #{inspect(Node.list())}", %{node: node()})
Process.send_after(self(), :check, 1_000)

{:noreply, state}
end
end
30 changes: 30 additions & 0 deletions example/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Example.MixProject do
use Mix.Project

def project do
[
app: :example,
version: "0.1.0",
elixir: "~> 1.15",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger],
mod: {Example, []}
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:libcluster, "~> 3.3"},
{:postgrex, ">= 0.0.0"},
{:libcluster_postgres, path: "../"}
]
end
end
8 changes: 8 additions & 0 deletions example/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%{
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"libcluster": {:hex, :libcluster, "3.3.3", "a4f17721a19004cfc4467268e17cff8b1f951befe428975dd4f6f7b84d927fe0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7c0a2275a0bb83c07acd17dab3c3bfb4897b145106750eeccc62d302e3bdfee5"},
"postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
}
26 changes: 0 additions & 26 deletions integration_test.exs

This file was deleted.

12 changes: 0 additions & 12 deletions test.sh

This file was deleted.