summaryrefslogtreecommitdiff
path: root/src/flagd-ui/lib/flagd_ui/storage.ex
diff options
context:
space:
mode:
authorSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
committerSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
commit82e03978b89938219958032efb1448cc76baa181 (patch)
tree626f3e54d52ecd49be0ed3bee30abacc0453d081 /src/flagd-ui/lib/flagd_ui/storage.ex
Initial snapshot - OpenTelemetry demo 2.1.3 -f
Diffstat (limited to 'src/flagd-ui/lib/flagd_ui/storage.ex')
-rw-r--r--src/flagd-ui/lib/flagd_ui/storage.ex71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/flagd-ui/lib/flagd_ui/storage.ex b/src/flagd-ui/lib/flagd_ui/storage.ex
new file mode 100644
index 0000000..eefcb13
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui/storage.ex
@@ -0,0 +1,71 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUi.Storage do
+ @moduledoc """
+ Storage module. This module initializes a process as a separate GenServer
+ to linearize reads and writes preventing conflicts and last-writer-wins.
+ """
+
+ use GenServer
+ require Logger
+
+ @file_path Application.compile_env!(:flagd_ui, :storage_file_path)
+
+ def start_link(opts) do
+ name = Keyword.get(opts, :name, Storage)
+
+ GenServer.start_link(__MODULE__, %{}, name: name)
+ end
+
+ @impl true
+ def init(_) do
+ state = @file_path |> File.read!() |> Jason.decode!()
+ Logger.info("Read new state from file")
+
+ {:ok, state}
+ end
+
+ @impl true
+ def handle_call(:read, _from, state) do
+ {:reply, state, state}
+ end
+
+ @impl true
+ def handle_cast({:replace, json_string}, _) do
+ new_state = Jason.decode!(json_string)
+
+ write_state(json_string)
+
+ {:noreply, new_state}
+ end
+
+ @impl true
+ def handle_cast({:write, flag_name, flag_value}, state) do
+ new_state =
+ Map.update(state, "flags", %{}, fn flags ->
+ update_flag(flags, flag_name, flag_value)
+ end)
+
+ json_state = Jason.encode!(new_state, pretty: true)
+
+ write_state(json_state)
+
+ {:noreply, new_state}
+ end
+
+ defp update_flag(flags, flag_name, value) do
+ flags
+ |> Enum.map(fn
+ {flag, data} when flag == flag_name -> {flag, Map.replace(data, "defaultVariant", value)}
+ {flag, data} -> {flag, data}
+ end)
+ |> Map.new()
+ end
+
+ defp write_state(json_string) do
+ File.write!(@file_path, json_string)
+
+ Logger.info("Wrote new state to file")
+ end
+end