From b415b3818465ceaabc8e56eb17ae6208ce2c6c8e Mon Sep 17 00:00:00 2001 From: Joao P Dubas Date: Mon, 10 Jun 2024 12:11:18 +0000 Subject: [PATCH] feat(growth): load data on application start To make this possible, the following changes were made: * Use `Task` to start the load process * Create `ets` table before start the async task * This is needed to keep the tables alive after the task process exits * Adjust the application to start the `Growth.Indicators.Load` task --- lib/growth/indicators/load.ex | 43 +++++++++++++++++++++++++---------- lib/wabanex/application.ex | 3 ++- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/lib/growth/indicators/load.ex b/lib/growth/indicators/load.ex index 8b5df89..9aa0232 100644 --- a/lib/growth/indicators/load.ex +++ b/lib/growth/indicators/load.ex @@ -32,6 +32,8 @@ defmodule Growth.Indicators.Load do """ + use Task + alias Growth.Score @measure_to_score [ @@ -45,6 +47,15 @@ defmodule Growth.Indicators.Load do weight_for_height: Score.WeightForHeight ] + @doc false + def start_link(_) do + Enum.map(@measure_to_score, fn {_, measure} -> + create_ets(measure) + end) + + Task.start_link(__MODULE__, :all, []) + end + @spec all :: [[boolean()]] @doc """ Load indicators csv files into their own ets tables. @@ -57,20 +68,13 @@ defmodule Growth.Indicators.Load do |> Task.await_many() end - @spec create_ets(String.t()) :: {atom(), String.t()} + @spec create_ets(module()) :: module() @doc """ - Create a public ets table for the csv filename, using the file name as the table name. + Create a public ets table for the growth module, using it as the table name. - Returns a tuple with table name as an atom and the filename. + Returns the given module. """ - def create_ets(filename) do - measure = - filename - |> Path.basename() - |> Path.rootname() - |> String.to_atom() - |> then(&Keyword.get(@measure_to_score, &1, &1)) - + def create_ets(measure) do try do :ets.new(measure, [:set, :public, :named_table]) rescue @@ -78,6 +82,21 @@ defmodule Growth.Indicators.Load do nil end + measure + end + + @spec filename_to_measure(String.t()) :: {atom(), String.t()} + @doc """ + Translate the given filename to the related module and return both in a tuple. + """ + def filename_to_measure(filename) do + measure = + filename + |> Path.basename() + |> Path.rootname() + |> String.to_atom() + |> then(&Keyword.get(@measure_to_score, &1, &1)) + {measure, filename} end @@ -127,7 +146,7 @@ defmodule Growth.Indicators.Load do as_float(t) end - key = {String.to_existing_atom(gender), unit, converted_t} + key = {String.to_atom(gender), unit, converted_t} value = %{ l: as_float(l), diff --git a/lib/wabanex/application.ex b/lib/wabanex/application.ex index 2960117..59b041a 100644 --- a/lib/wabanex/application.ex +++ b/lib/wabanex/application.ex @@ -16,9 +16,10 @@ defmodule Wabanex.Application do # Start the PubSub system {Phoenix.PubSub, name: Wabanex.PubSub}, # Start the Endpoint (http/https) - WabanexWeb.Endpoint + WabanexWeb.Endpoint, # Start a worker by calling: Wabanex.Worker.start_link(arg) # {Wabanex.Worker, arg} + {Growth.Indicators.Load, []} ] # See https://hexdocs.pm/elixir/Supervisor.html