Merge branch 'feature/parallel-rendering' into 'develop'

Parallelize template rendering

See merge request pleroma/pleroma!1576
This commit is contained in:
lain 2019-08-15 15:51:11 +00:00
commit aefb9cdee8
3 changed files with 48 additions and 12 deletions

View file

@ -37,17 +37,37 @@ def run(["render_timeline", nickname]) do
|> Map.put("blocking_user", user) |> Map.put("blocking_user", user)
|> Map.put("muting_user", user) |> Map.put("muting_user", user)
|> Map.put("user", user) |> Map.put("user", user)
|> Map.put("limit", 80)
|> Pleroma.Web.ActivityPub.ActivityPub.fetch_public_activities() |> Pleroma.Web.ActivityPub.ActivityPub.fetch_public_activities()
|> Enum.reverse() |> Enum.reverse()
Benchee.run(%{ inputs = %{
"render_timeline" => fn -> "One activity" => Enum.take_random(activities, 1),
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{ "Ten activities" => Enum.take_random(activities, 10),
activities: activities, "Twenty activities" => Enum.take_random(activities, 20),
for: user, "Forty activities" => Enum.take_random(activities, 40),
as: :activity "Eighty activities" => Enum.take_random(activities, 80)
}) }
end
}) Benchee.run(
%{
"Parallel rendering" => fn activities ->
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
activities: activities,
for: user,
as: :activity
})
end,
"Standart rendering" => fn activities ->
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
activities: activities,
for: user,
as: :activity,
parallel: false
})
end
},
inputs: inputs
)
end end
end end

View file

@ -70,12 +70,14 @@ defp reblogged?(activity, user) do
def render("index.json", opts) do def render("index.json", opts) do
replied_to_activities = get_replied_to_activities(opts.activities) replied_to_activities = get_replied_to_activities(opts.activities)
parallel = unless is_nil(opts[:parallel]), do: opts[:parallel], else: true
opts.activities opts.activities
|> safe_render_many( |> safe_render_many(
StatusView, StatusView,
"status.json", "status.json",
Map.put(opts, :replied_to_activities, replied_to_activities) Map.put(opts, :replied_to_activities, replied_to_activities),
parallel
) )
end end

View file

@ -66,9 +66,23 @@ def safe_render(view, template, assigns \\ %{}) do
end end
@doc """ @doc """
Same as `render_many/4` but wrapped in rescue block. Same as `render_many/4` but wrapped in rescue block and parallelized (unless disabled by passing false as a fifth argument).
""" """
def safe_render_many(collection, view, template, assigns \\ %{}) do def safe_render_many(collection, view, template, assigns \\ %{}, parallel \\ true)
def safe_render_many(collection, view, template, assigns, true) do
Enum.map(collection, fn resource ->
Task.async(fn ->
as = Map.get(assigns, :as) || view.__resource__
assigns = Map.put(assigns, as, resource)
safe_render(view, template, assigns)
end)
end)
|> Enum.map(&Task.await(&1, :infinity))
|> Enum.filter(& &1)
end
def safe_render_many(collection, view, template, assigns, false) do
Enum.map(collection, fn resource -> Enum.map(collection, fn resource ->
as = Map.get(assigns, :as) || view.__resource__ as = Map.get(assigns, :as) || view.__resource__
assigns = Map.put(assigns, as, resource) assigns = Map.put(assigns, as, resource)