Packages
localize
0.30.1
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.41.3
0.41.2
0.41.1
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.1
0.30.0
retired
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
0.1.0-alpha.1
Localization (parsing, formatting) of numbers, dates/time/calendar, units of measure, messages and lists. Includes localized collation.
Current section
Files
Jump to
Current section
Files
lib/localize/locale/cache_sweeper.ex
defmodule Localize.Locale.CacheSweeper do
@moduledoc false
use GenServer
@table :localize_locale_cache
@sweep_interval_ms 10_000
# Top 50 languages by native speaker population (lowercase
# canonical form matching the ETS cache key format). These
# entries are never evicted during cache sweeps.
@never_evict MapSet.new([
"zh",
"es",
"en",
"hi",
"ar",
"bn",
"pt",
"ru",
"ja",
"pa",
"de",
"jv",
"ko",
"fr",
"te",
"mr",
"tr",
"ta",
"vi",
"ur",
"it",
"th",
"gu",
"pl",
"uk",
"ml",
"kn",
"or",
"my",
"sw",
"su",
"ro",
"nl",
"ha",
"az",
"si",
"hu",
"zu",
"cs",
"el",
"sv",
"be",
"da",
"fi",
"sk",
"no",
"he",
"id",
"ms",
"fil"
])
def start_link(_options) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@impl true
def init([]) do
schedule_sweep()
{:ok, []}
end
@impl true
def handle_info(:sweep, state) do
sweep()
schedule_sweep()
{:noreply, state}
end
defp schedule_sweep do
Process.send_after(self(), :sweep, @sweep_interval_ms)
end
defp sweep do
if :ets.whereis(@table) != :undefined do
max_entries = Application.get_env(:localize, :locale_cache_max_entries, 1_000)
size = :ets.info(@table, :size)
if size > max_entries do
evict_random(size - max_entries)
end
end
end
defp evict_random(count) when count <= 0, do: :ok
defp evict_random(count) do
key = :ets.first(@table)
evict_random(key, count)
end
defp evict_random(:"$end_of_table", _remaining), do: :ok
defp evict_random(_key, 0), do: :ok
defp evict_random(key, remaining) do
next_key = :ets.next(@table, key)
if key in @never_evict do
evict_random(next_key, remaining)
else
if :rand.uniform() < 0.5 do
# Table is `:protected` and owned by `Localize.Locale.Loader`;
# delete via the owner. Cast (not call) so the sweeper never
# blocks the owner's load_and_store handler.
GenServer.cast(Localize.Locale.Loader, {:cache_evict, key})
evict_random(next_key, remaining - 1)
else
evict_random(next_key, remaining)
end
end
end
end