Packages

ex_cldr

2.45.0
2.47.5 2.47.4 2.47.3 2.47.2 2.47.1 2.47.0 2.46.0 2.45.2 2.45.1 2.45.0 2.44.1 2.44.0 2.43.2 2.43.1 2.43.0 2.42.0 2.41.1 2.41.0 2.40.4 2.40.3 2.40.2 2.40.1 2.40.0 2.39.2 2.39.1 2.39.0 2.38.1 2.38.0 2.37.5 2.37.4 2.37.3 retired 2.37.2 2.37.1 2.37.0 2.36.0 2.35.1 2.35.0 retired 2.34.2 2.34.1 2.34.0 2.33.2 2.33.1 2.33.1-rc.0 2.33.0 2.32.1 2.32.0 2.31.0 2.30.0 2.29.0 2.28.0 2.27.1 2.27.0 retired 2.26.3 2.26.2 2.26.1 2.26.0 2.25.0 2.24.2 2.24.1 2.24.0 2.24.0-rc.6 2.24.0-rc.5 2.24.0-rc.4 2.24.0-rc.3 2.24.0-rc.2 2.24.0-rc.1 2.24.0-rc.0 2.23.2 2.23.1 2.23.0 2.22.1 2.22.0 2.21.0 2.20.0 2.20.0-rc.3 2.20.0-rc.2 2.20.0-rc.1 2.20.0-rc.0 2.19.1 2.19.0 2.18.2 2.18.1 2.18.0 2.18.0-rc.0 2.17.2 2.17.1 2.17.0 2.16.2 2.16.1 2.16.1-rc.0 2.16.0 2.15.0 2.14.1 2.14.0 2.14.0-rc.0 2.13.0 2.12.1 2.12.0 2.11.1 2.11.0 2.10.2 2.10.1 2.10.0 retired 2.9.0 2.8.1 2.8.0 2.7.2 2.7.1 2.7.0 2.6.2 2.6.1 2.6.0 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.2 2.3.1 2.3.0 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 2.0.0-rc.3 retired 2.0.0-rc.2 retired 2.0.0-rc.1 retired 2.0.0-rc.0 retired 1.8.2 1.8.1 1.8.0 1.7.1 1.7.0 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.2 1.5.1 1.5.0 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 retired 1.4.0-rc.3 retired 1.4.0-rc.2 retired 1.4.0-rc.1 retired 1.4.0-rc.0 retired 1.3.2 1.3.1 1.3.0 1.2.0 1.1.0 1.0.0 1.0.0-rc.3 retired 1.0.0-rc.2 retired 1.0.0-rc.1 retired 1.0.0-rc.0 retired 0.13.1 0.13.0 0.12.2 retired 0.12.1 retired 0.12.0 retired 0.11.0 retired 0.10.0 retired 0.9.0 retired 0.8.3 retired 0.8.2 retired 0.8.1 retired 0.8.0 retired 0.7.0 retired 0.6.2 retired 0.6.1 retired 0.6.0 retired 0.5.2 retired 0.5.1 retired 0.5.0 retired 0.4.2 retired 0.4.1 retired 0.4.0 retired 0.3.0 retired 0.2.1 retired 0.2.0 retired 0.1.3 retired 0.1.2 retired 0.1.1 retired 0.1.0 retired 0.0.20 retired 0.0.19 retired 0.0.18 retired 0.0.17 retired 0.0.16 retired 0.0.15 retired 0.0.14 retired 0.0.13 retired 0.0.12 retired 0.0.11 retired 0.0.10 retired 0.0.8 retired 0.0.7 retired 0.0.6 retired 0.0.5 retired 0.0.4 retired 0.0.3 retired

Common Locale Data Repository (CLDR) functions for Elixir to localize and format numbers, dates, lists, messages, languages, territories and units with support for over 700 locales for internationalized (i18n) and localized (L10N) applications.

Current section

Files

Jump to
ex_cldr lib cldr locale cache.ex
Raw

lib/cldr/locale/cache.ex

defmodule Cldr.Locale.Cache do
@moduledoc false
# Caches locales in an :ets table
# during compilation to improve performance
use GenServer
alias Cldr.Locale.Loader
@table_name :cldr_locales
@gen_server_name :cldr_locale_cache
# @timeout 5_000
# Client
def start(args \\ []) do
GenServer.start(__MODULE__, args, name: @gen_server_name)
end
def get_locale(locale, path) do
ensure_genserver_started!()
do_get_locale(locale, path)
end
def get_language_tag(locale) do
ensure_genserver_started!()
do_get_language_tag(locale)
end
def compiling? do
# TODO: When we depend on Elixir v1.11+, remove function_exported and elixir_compiler_pid
process_alive?(:can_await_module_compilation?) ||
process_alive?(:elixir_compiler_pid) ||
process_alive?(:cldr_locale_cache)
end
defp process_alive?(:can_await_module_compilation?) do
Code.ensure_loaded?(Code) &&
function_exported?(Code, :can_await_module_compilation?, 0) &&
apply(Code, :can_await_module_compilation?, [])
end
defp process_alive?(name) do
case Process.get(name) do
nil -> false
pid when is_pid(pid) -> true
end
end
def put_all_language_tags(language_tags) do
for {locale, language_tag} <- language_tags do
:ets.insert(@table_name, {{:tag, locale}, language_tag})
end
end
defp ensure_genserver_started! do
if compiling?() and not gen_server_started?() do
Cldr.maybe_log("Starting the compiler locale cache")
case start() do
{:ok, _pid} -> :ok
{:error, {:already_started, _pid}} -> :ok
end
end
end
# Server (callbacks)
def init(_args) do
# Create the ets table and return its reference
# as the state. State therefore is only the
# reference to the ets table we use for caching
create_ets_table!()
all_language_tags = Cldr.Config.all_language_tags()
put_all_language_tags(all_language_tags)
Process.flag(:trap_exit, true)
{:ok, @table_name}
end
def handle_call({:get_locale, locale_name, path}, _from, state) do
locale = do_get_locale(locale_name, path)
{:reply, locale, state}
end
# handle the trapped exit call
def handle_info({:EXIT, _from, reason}, state) do
Cldr.maybe_log("Compile locale cache received EXIT message: #{inspect(reason)}")
{:stop, reason, state}
end
def terminate(reason, _) do
Cldr.maybe_log("Compile locale cache is terminating: #{inspect(reason)}")
end
def gen_server_started? do
case Process.whereis(@gen_server_name) do
nil -> false
pid when is_pid(pid) -> true
end
end
defp do_get_locale(locale, path) do
case :ets.lookup(@table_name, locale) do
[{^locale, locale_data}] ->
Cldr.maybe_log("Compiler locale cache: Hit for locale #{inspect(locale)}.")
locale_data
[] ->
Cldr.maybe_log(
"Compiler locale cache: Miss for #{inspect(locale)}. " <>
"Reading and decoding the locale file."
)
locale_data = Loader.do_get_locale(locale, path, false)
try do
:ets.insert(@table_name, {locale, locale_data})
rescue
ArgumentError ->
nil
# This may actually happen because of timing conditions: someone else may
# have inserted behind our back. But since we've now already generated
# the locale again just use it.
Cldr.maybe_log(
"Compiler locale cache: Error: Could not insert " <>
"locale #{inspect(locale)} into cache. Assuming locale is already cached."
)
end
locale_data
other ->
raise RuntimeError, inspect(other)
end
rescue
ArgumentError ->
# We can very occasionally get an exception when the gen_server
# is started but before the table is created and another thread
# tries to get a locale. In this case we just get the locale manually
Loader.do_get_locale(locale, path, false)
end
defp do_get_language_tag(locale) do
case :ets.lookup(@table_name, {:tag, locale}) do
[{{:tag, ^locale}, language_tag}] ->
Cldr.maybe_log("Compiler language tag cache: Hit for locale #{inspect(locale)}.")
language_tag
[] ->
# A new locale for which there is no precomputed language tag yet
# In fact that's probably what we're about to do later on - create the
# precomputed tag.
Cldr.maybe_log("Compiler language tag cache miss for locale #{inspect(locale)}.")
nil
end
end
# We assign the compiler pid as the heir for our table so
# that the table doesn't die with each compilation thread
# This is undoubtedly hacky.
defp create_ets_table! do
case :ets.info(@table_name) do
:undefined ->
:ets.new(@table_name, [:named_table, :public, {:read_concurrency, true}])
Cldr.maybe_log("Compiler locale cache: Created cache #{inspect(@table_name)} in :ets")
_ ->
:ok
end
end
end