Skip to content

Commit

Permalink
Removed predictions injection
Browse files Browse the repository at this point in the history
  • Loading branch information
kotva006 committed May 9, 2024
1 parent 8b60f94 commit 0741e96
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 80 deletions.
16 changes: 7 additions & 9 deletions lib/dotcom/realtime_schedule.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ defmodule Dotcom.RealtimeSchedule do
@default_opts [
stops_fn: &StopsRepo.get/1,
routes_fn: &RoutesRepo.by_stop_with_route_pattern/1,
predictions_fn: Function.capture(@predictions_repo, :all_no_cache, 1),
schedules_fn: &SchedulesRepo.by_route_ids/2,
alerts_fn: &Alerts.Repo.by_route_ids/2
]
Expand All @@ -53,7 +52,6 @@ defmodule Dotcom.RealtimeSchedule do
opts = Keyword.merge(@default_opts, opts)
stops_fn = Keyword.fetch!(opts, :stops_fn)
routes_fn = Keyword.fetch!(opts, :routes_fn)
predictions_fn = Keyword.fetch!(opts, :predictions_fn)
schedules_fn = Keyword.fetch!(opts, :schedules_fn)
alerts_fn = Keyword.fetch!(opts, :alerts_fn)

Expand All @@ -63,7 +61,7 @@ defmodule Dotcom.RealtimeSchedule do

# stage 2, get stops, predictions, schedules, and alerts
stops_task = Task.async(fn -> get_stops(stop_ids, stops_fn) end)
predictions_task = Task.async(fn -> get_predictions(route_with_patterns, predictions_fn) end)
predictions_task = Task.async(fn -> get_predictions(route_with_patterns) end)
schedules_task = Task.async(fn -> get_schedules(route_with_patterns, now, schedules_fn) end)

alerts_task = Task.async(fn -> get_alerts(route_with_patterns, now, alerts_fn) end)
Expand Down Expand Up @@ -129,12 +127,12 @@ defmodule Dotcom.RealtimeSchedule do
|> json_safe_alerts(now)
end

@spec get_predictions([route_with_patterns_t], fun()) :: map
defp get_predictions(route_with_patterns, predictions_fn) do
@spec get_predictions([route_with_patterns_t]) :: map
defp get_predictions(route_with_patterns) do
route_with_patterns
|> Enum.map(fn {stop_id, _route, route_patterns} ->
Task.async(fn ->
do_get_predictions(stop_id, route_patterns, predictions_fn)
do_get_predictions(stop_id, route_patterns)
end)
end)
|> Enum.flat_map(&Task.await(&1, @long_timeout))
Expand Down Expand Up @@ -162,13 +160,13 @@ defmodule Dotcom.RealtimeSchedule do
end
end

@spec do_get_predictions(Stop.id_t(), [RoutePattern.t()], fun()) :: [
@spec do_get_predictions(Stop.id_t(), [RoutePattern.t()]) :: [
{
route_pattern_name_t,
[Prediction.t()]
}
]
defp do_get_predictions(stop_id, route_patterns, predictions_fn) do
defp do_get_predictions(stop_id, route_patterns) do
route_patterns
|> Enum.map(fn route_pattern ->
key = route_pattern_key(route_pattern, stop_id)
Expand All @@ -181,7 +179,7 @@ defmodule Dotcom.RealtimeSchedule do
sort: "time",
"page[limit]": @predicted_schedules_per_stop
]
|> predictions_fn.()
|> @predictions_repo.all_no_cache()
|> Enum.filter(& &1.time)

{key, next_two_predictions}
Expand Down
5 changes: 1 addition & 4 deletions lib/dotcom/transit_near_me.ex
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,9 @@ defmodule Dotcom.TransitNearMe do
PredictedSchedule.t()
]
defp get_predicted_schedules(schedules, params, opts) do
predictions_fn =
Keyword.get(opts, :predictions_fn, Function.capture(@predictions_repo, :all, 1))

now = Keyword.fetch!(opts, :now)

predictions = predictions_fn.(params)
predictions = @predictions_repo.all(params)

if predictions == [] do
Logger.warning("#{__MODULE__} no.predictions.for.schedule #{inspect(params)}")
Expand Down
5 changes: 1 addition & 4 deletions lib/dotcom_web/controllers/schedule/finder_api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,9 @@ defmodule DotcomWeb.ScheduleController.FinderApi do
direction_id: direction_id
]

predictions_fn =
Map.get(conn.assigns, :predictions_fn, Function.capture(@predictions_repo, :all, 1))

predictions =
if current_service?,
do: predictions_fn.(prediction_opts) |> Enum.filter(&(&1.stop.id == stop_id)),
do: @predictions_repo.all(prediction_opts) |> Enum.filter(&(&1.stop.id == stop_id)),
else: []

{schedules, predictions}
Expand Down
9 changes: 3 additions & 6 deletions lib/dotcom_web/controllers/schedule/green.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ defmodule DotcomWeb.ScheduleController.Green do
plug(:channels)

@task_timeout 10_000
@predictions_repo Application.compile_env!(:dotcom, :repo_modules)[:predictions]

def show(%Plug.Conn{query_params: %{"tab" => "alerts"}} = conn, _params),
do: alerts(conn, [])
Expand Down Expand Up @@ -73,24 +72,22 @@ defmodule DotcomWeb.ScheduleController.Green do
assign(conn, :stops_on_routes, GreenLine.stops_on_routes(direction_id, date))
end

def predictions(conn, opts) do
def predictions(conn, _opts) do
{predictions, vehicle_predictions} =
if DotcomWeb.ScheduleController.Predictions.should_fetch_predictions?(conn) do
predictions_fn = Function.capture(@predictions_repo, :all, 1)

predictions_stream =
conn
|> conn_with_branches
|> Task.async_stream(
fn conn ->
DotcomWeb.ScheduleController.Predictions.predictions(conn, predictions_fn)
DotcomWeb.ScheduleController.Predictions.predictions(conn)
end,
timeout: @task_timeout,
on_timeout: :kill_task
)

vehicle_predictions =
DotcomWeb.ScheduleController.Predictions.vehicle_predictions(conn, predictions_fn)
DotcomWeb.ScheduleController.Predictions.vehicle_predictions(conn)

{flat_map_results(predictions_stream), vehicle_predictions}
else
Expand Down
2 changes: 1 addition & 1 deletion lib/dotcom_web/controllers/schedule/line_api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ defmodule DotcomWeb.ScheduleController.LineApi do
conn
|> DateInRating.call(opts)
|> Green.vehicle_locations(VehicleLocations.init(opts))
|> Green.predictions(Predictions.init(opts))
|> Green.predictions(opts)
|> VehicleTooltips.call(opts)
end

Expand Down
49 changes: 21 additions & 28 deletions lib/dotcom_web/controllers/schedule/predictions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,18 @@ defmodule DotcomWeb.ScheduleController.Predictions do

@predictions_repo Application.compile_env!(:dotcom, :repo_modules)[:predictions]

@typep predictions_fn :: (Keyword.t() -> [Prediction.t()] | {:error, any})

@impl true
def init(opts \\ []) do
Keyword.merge([predictions_fn: Function.capture(@predictions_repo, :all, 1)], opts)
end
def init(opts \\ []), do: opts

@impl true
def call(conn, opts) do
Util.log_duration(__MODULE__, :do_call, [conn, opts])
def call(conn, _opts \\ []) do
Util.log_duration(__MODULE__, :do_call, [conn])
end

def do_call(conn, opts) do
def do_call(conn) do
if should_fetch_predictions?(conn) do
predictions_task = fn -> predictions(conn, opts[:predictions_fn]) end
vehicle_predictions_task = fn -> vehicle_predictions(conn, opts[:predictions_fn]) end
predictions_task = fn -> predictions(conn) end
vehicle_predictions_task = fn -> vehicle_predictions(conn) end

conn
|> AsyncAssign.async_assign_default(:predictions, predictions_task, [])
Expand All @@ -52,18 +48,15 @@ defmodule DotcomWeb.ScheduleController.Predictions do
Date.compare(assigns.date, Util.service_date(assigns.date_time)) == :eq
end

@spec predictions(Plug.Conn.t(), predictions_fn) :: [Prediction.t()]
def predictions(
%{
assigns: %{
origin: origin,
destination: destination,
route: %{id: route_id},
direction_id: direction_id
}
},
predictions_fn
)
@spec predictions(Plug.Conn.t()) :: [Prediction.t()]
def predictions(%{
assigns: %{
origin: origin,
destination: destination,
route: %{id: route_id},
direction_id: direction_id
}
})
when not is_nil(origin) do
destination_id = if destination, do: Map.get(destination, :id)

Expand All @@ -74,7 +67,7 @@ defmodule DotcomWeb.ScheduleController.Predictions do
[route: route_id, direction_id: direction_id]
end

predictions_fn.(opts)
@predictions_repo.all(opts)
|> case do
{:error, error} ->
Logger.error("predictions for opts #{inspect(opts)}: #{inspect(error)}")
Expand All @@ -91,7 +84,7 @@ defmodule DotcomWeb.ScheduleController.Predictions do
end
end

def predictions(_conn, _) do
def predictions(_conn) do
[]
end

Expand All @@ -112,16 +105,16 @@ defmodule DotcomWeb.ScheduleController.Predictions do
end)
end

@spec vehicle_predictions(Plug.Conn.t(), predictions_fn) :: [Prediction.t()]
def vehicle_predictions(%{assigns: %{vehicle_locations: vehicle_locations}}, predictions_fn) do
@spec vehicle_predictions(Plug.Conn.t()) :: [Prediction.t()]
def vehicle_predictions(%{assigns: %{vehicle_locations: vehicle_locations}}) do
{trip_ids, stop_ids} =
vehicle_locations
|> Map.keys()
|> Enum.unzip()

trip_ids = trip_ids |> Enum.reject(&is_nil/1) |> Enum.join(",")

case predictions_fn.(trip: trip_ids) do
case @predictions_repo.all(trip: trip_ids) do
{:error, error} ->
Logger.error("predictions for trips #{inspect(trip_ids)}: #{inspect(error)}")

Expand All @@ -133,7 +126,7 @@ defmodule DotcomWeb.ScheduleController.Predictions do
end
end

def vehicle_predictions(_conn, _) do
def vehicle_predictions(_conn) do
[]
end
end
5 changes: 1 addition & 4 deletions lib/predicted_schedule.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ defmodule PredictedSchedule do
def get(route_id, stop_id, opts \\ []) do
schedules_fn = Keyword.get(opts, :schedules_fn, &Schedules.Repo.by_route_ids/2)

predictions_fn =
Keyword.get(opts, :predictions_fn, Function.capture(@predictions_repo, :all, 1))

now = Keyword.get(opts, :now, Util.now())
direction_id = Keyword.get(opts, :direction_id)
sort_fn = Keyword.get(opts, :sort_fn, &sort_predicted_schedules/1)
Expand Down Expand Up @@ -58,7 +55,7 @@ defmodule PredictedSchedule do

predicted_schedules =
[route: route_id, direction_id: direction_id]
|> predictions_fn.()
|> @predictions_repo.all()
|> Enum.filter(&(&1.stop.id == stop_id))
|> PredictedSchedule.group(schedules, sort_fn: sort_fn)
|> filter_predicted_schedules(now)
Expand Down
24 changes: 4 additions & 20 deletions test/dotcom_web/controllers/schedule/predictions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,8 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do
import Mox
alias Predictions.Prediction

defmodule PredictionsTest do
# needs to be a separate module so that it's defined before the test uses
# it
def all(_) do
[]
end
end

@empty [%Prediction{}]

@opts init(predictions_fn: &PredictionsTest.all/1)

setup %{conn: conn} do
conn =
conn
Expand All @@ -26,19 +16,13 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do
{:ok, %{conn: conn}}
end

describe "init/1" do
test "defaults to using Predictions.Repo.Mock.all" do
assert init() == [predictions_fn: &Predictions.Repo.Mock.all/1]
end
end

describe "call/2" do
test "when given a date that isn't the service date, assigns no predictions", %{conn: conn} do
conn =
conn
|> assign(:date, ~D[2016-12-31])
|> assign(:origin, Faker.Pokemon.location())
|> call(@opts)
|> call([])

assert conn.assigns[:predictions] == []
assert conn.assigns[:vehicle_predictions] == []
Expand All @@ -48,7 +32,7 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do
conn =
conn
|> assign(:origin, nil)
|> call(@opts)
|> call([])

assert conn.assigns[:predictions] == []
assert conn.assigns[:vehicle_predictions] == []
Expand Down Expand Up @@ -160,7 +144,7 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do
|> assign(:destination, nil)
|> assign(:route, %{id: "4"})
|> assign(:direction_id, "0")
|> call(init())
|> call()

assert conn.assigns.predictions == []
end
Expand All @@ -183,7 +167,7 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do
|> assign(:destination, nil)
|> assign(:route, %{id: "4"})
|> assign(:direction_id, "0")
|> call(init())
|> call()

assert conn.assigns.predictions == [prediction]
end
Expand Down
7 changes: 3 additions & 4 deletions test/predicted_schedule_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,16 @@ defmodule PredictedScheduleTest do
@trip_schedules
end

predictions_fn = fn opts ->
expect(Predictions.Repo.Mock, :all, fn opts ->
refute Keyword.has_key?(opts, :min_time)
@trip_predictions
end
end)

predicted_schedules =
get("Teal", "stop1",
# between scheduled and predicted times for Trip 2
now: Timex.shift(@base_time, minutes: 11),
schedules_fn: schedules_fn,
predictions_fn: predictions_fn
schedules_fn: schedules_fn
)

# should not see Trip 1 since scheduled and predicted times have passed
Expand Down

0 comments on commit 0741e96

Please sign in to comment.