Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cache routes by id to speed up alerts filtering #2142

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ config :screens, Screens.ScreenApiResponseCache,
allocated_memory: 250_000_000

config :screens, Screens.Stops.StopsToRoutes, adapter: Nebulex.Adapters.Local
config :screens, Screens.Routes.RoutesCache, adapter: Nebulex.Adapters.Local

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
Expand Down
3 changes: 2 additions & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ config :screens,
blue_bikes_station_status_url: [:no_api_requests_allowed_during_testing],
blue_bikes_api_client: Screens.BlueBikes.FakeClient,
stops_to_routes_route_mod: Screens.Routes.Route.Mock,
alerts_cache_filter_route_mod: Screens.Routes.Route.Mock,
routes_cache_route_mod: Screens.Routes.Route.Mock,
dup_headsign_replacements: %{
"Test 1" => "T1"
},
Expand Down Expand Up @@ -164,3 +164,4 @@ config :screens, :screens_by_alert,
screens_ttl_seconds: 1

config :screens, Screens.Stops.StopsToRoutes, adapter: Nebulex.Adapters.Nil
config :screens, Screens.Routes.RoutesCache, adapter: Nebulex.Adapters.Nil
7 changes: 3 additions & 4 deletions lib/screens/alerts/cache/filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ defmodule Screens.Alerts.Cache.Filter do
Logic to apply filters to a list of `Screens.Alerts.Alert` structs.
"""
alias Screens.Routes.Route
alias Screens.Routes.RoutesCache
alias Screens.RouteType
alias Screens.Stops.StopsToRoutes

@route_mod Application.compile_env(:screens, :alerts_cache_filter_route_mod, Route)

@default_activities ~w[BOARD EXIT RIDE]

@type filter_opts() :: %{
Expand Down Expand Up @@ -127,8 +126,8 @@ defmodule Screens.Alerts.Cache.Filter do
end

defp matchers_for_route_id(route_id) do
case @route_mod.by_id(route_id) do
{:ok, %Route{type: type}} ->
case RoutesCache.by_id(route_id) do
%Route{type: type} ->
[
%{
route_type: RouteType.to_id(type),
Expand Down
3 changes: 2 additions & 1 deletion lib/screens/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ defmodule Screens.Application do
{Screens.OlCrowding.Agent, %{}},
{Screens.ScreenApiResponseCache, []},
Screens.Streams.Alerts,
Screens.Stops.StopsToRoutes
Screens.Stops.StopsToRoutes,
Screens.Routes.RoutesCache
]

# See https://hexdocs.pm/elixir/Supervisor.html
Expand Down
39 changes: 39 additions & 0 deletions lib/screens/routes/routes_cache.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule Screens.Routes.RoutesCache do
@moduledoc """
A read-through cache of routes by ID.
"""
use Nebulex.Cache,
otp_app: :screens,
adapter: Application.compile_env(:screens, [__MODULE__, :adapter])

alias Screens.Routes.Route

@route_mod Application.compile_env(:screens, :routes_cache_route_mod, Screens.Routes.Route)

@base_ttl :timer.hours(1)

@spec by_id(id :: String.t()) :: Route.t() | nil
def by_id(id) do
if route = get(id) do
route
else
route = fetch_by_id(id)

unless is_nil(route), do: put(id, route, ttl: ttl())

route
end
end

defp fetch_by_id(id) do
case @route_mod.by_id(id) do
{:ok, %Route{} = route} -> route
_ -> nil
end
end

def ttl do
additional_minutes = :rand.uniform(30)
@base_ttl + :timer.minutes(additional_minutes)
end
end
Loading