From 8637133225e8c806308ac9f93956a150fb175868 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Sun, 7 Apr 2024 16:44:16 +0200 Subject: [PATCH] feature: implement clustering (#280) --- .../workflows/on_push_branch__execute_ci_cd.yml | 2 +- config/runtime.exs | 16 ++++++++++++++++ lib/mindwendel/application.ex | 13 +++++++++++++ mix.exs | 3 ++- mix.lock | 1 + rel/overlays/bin/server | 10 ++++++++++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/.github/workflows/on_push_branch__execute_ci_cd.yml b/.github/workflows/on_push_branch__execute_ci_cd.yml index b2478d7d..39d49e55 100644 --- a/.github/workflows/on_push_branch__execute_ci_cd.yml +++ b/.github/workflows/on_push_branch__execute_ci_cd.yml @@ -15,7 +15,7 @@ jobs: # Currently, this need to be synced manually with the Dockerfile. In the future, the workflow should be changed, # so that a development container is built from the Dockerfile, pushed, and then re-used in the following steps. # This would also remove the need to install cmake manually in each step: - container: hexpm/elixir:1.15.2-erlang-26.0.2-debian-bullseye-20230612-slim + container: hexpm/elixir:1.15.7-erlang-26.2.2-debian-bullseye-20240130-slim steps: # See https://github.com/actions/checkout diff --git a/config/runtime.exs b/config/runtime.exs index 231d40eb..369acc1d 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -108,6 +108,22 @@ if config_env() != :test do # if config_env() == :prod do config :mindwendel, MindwendelWeb.Endpoint, server: true + + # Enable libcluster if set: + if System.get_env("MW_ENABLE_LIBCLUSTER") == "true" do + Logger.info("Configuring libcluster to use Kubernetes.DNS strategy") + + config :libcluster, + topologies: [ + k8s_mindwendel: [ + strategy: Elixir.Cluster.Strategy.Kubernetes.DNS, + config: [ + service: "mindwendel-cluster", + application_name: "mindwendel" + ] + ] + ] + end end # diff --git a/lib/mindwendel/application.ex b/lib/mindwendel/application.ex index 8f2f8910..b33ccb7f 100644 --- a/lib/mindwendel/application.ex +++ b/lib/mindwendel/application.ex @@ -38,6 +38,19 @@ defmodule Mindwendel.Application do {Oban, oban_config()} ] + children = + if Application.get_env(:libcluster, :topologies) do + Logger.info("Adding Cluster.Supervisor to Supervisor tree") + + children ++ + [ + {Cluster.Supervisor, + [Application.get_env(:libcluster, :topologies), [name: Mindwendel.ClusterSupervisor]]} + ] + else + children + end + # when logger_json is defined, we also want it to take care of ecto: if Application.get_env(:qrstorage, :logger_json) do :ok = diff --git a/mix.exs b/mix.exs index f8aa3ea2..6119b3ea 100644 --- a/mix.exs +++ b/mix.exs @@ -63,7 +63,8 @@ defmodule Mindwendel.MixProject do {:telemetry_metrics, "1.0.0"}, {:telemetry_poller, "1.0.0"}, {:timex, "3.7.11"}, - {:logger_json, "5.1.4"} + {:logger_json, "5.1.4"}, + {:libcluster, "3.3.3"} ] end diff --git a/mix.lock b/mix.lock index 9729ed6d..5e4bf18c 100644 --- a/mix.lock +++ b/mix.lock @@ -23,6 +23,7 @@ "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "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"}, "logger_json": {:hex, :logger_json, "5.1.4", "9e30a4f2e31a8b9e402bdc20bd37cf9b67d3a31f19d0b33082a19a06b4c50f6d", [:mix], [{:ecto, "~> 2.1 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.5.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "3f20eea58e406a33d3eb7814c7dff5accb503bab2ee8601e84da02976fa3934c"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, diff --git a/rel/overlays/bin/server b/rel/overlays/bin/server index 4497c3db..af370922 100755 --- a/rel/overlays/bin/server +++ b/rel/overlays/bin/server @@ -10,4 +10,14 @@ done ./mindwendel eval "Mindwendel.Release.migrate" +# This is required for libcluster, see https://hexdocs.pm/libcluster/Cluster.Strategy.Kubernetes.DNS.html +if [ -n "$POD_IP" ]; then + echo "Setting variables for libcluster" + export RELEASE_DISTRIBUTION=name + export RELEASE_NODE=mindwendel@${POD_IP} +else + echo "Not setting variables for libcluster" +fi + + PHX_SERVER=true exec ./mindwendel start