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

Optimize task list performance #1156

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions lib/code_corps_web/controllers/project_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ defmodule CodeCorpsWeb.ProjectController do
end

@preloads [
:donation_goals, [organization: :stripe_connect_account],
:project_categories, :project_github_repos, :project_skills,
:project_users, :stripe_connect_plan, :task_lists, :tasks
:donation_goals, [organization: [:organization_github_app_installations, :projects, :slugged_route, :stripe_connect_account]],
:project_categories, :project_github_repos, [project_skills: :skill],
[project_users: :user], :stripe_connect_plan, :task_lists, :tasks
]

def preload(data) do
Expand Down
17 changes: 13 additions & 4 deletions lib/code_corps_web/controllers/project_skill_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ defmodule CodeCorpsWeb.ProjectSkillController do

@spec index(Conn.t, map) :: Conn.t
def index(%Conn{} = conn, %{} = params) do
with project_skills <- ProjectSkill |> Query.id_filter(params) |> Repo.all do
with project_skills <- ProjectSkill |> Query.id_filter(params) |> Repo.all |> preload() do
conn |> render("index.json-api", data: project_skills)
end
end

@spec show(Conn.t, map) :: Conn.t
def show(%Conn{} = conn, %{"id" => id}) do
with %ProjectSkill{} = project_skill <- ProjectSkill |> Repo.get(id) do
with %ProjectSkill{} = project_skill <- ProjectSkill |> Repo.get(id) |> preload() do
conn |> render("show.json-api", data: project_skill)
end
end
Expand All @@ -26,8 +26,9 @@ defmodule CodeCorpsWeb.ProjectSkillController do
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %ProjectSkill{}, params),
{:ok, %ProjectSkill{} = project_skill} <- %ProjectSkill{} |> ProjectSkill.create_changeset(params) |> Repo.insert do

{:ok, %ProjectSkill{} = project_skill} <- %ProjectSkill{} |> ProjectSkill.create_changeset(params) |> Repo.insert(),
project_skill <- preload(project_skill)
do
current_user.id |> SegmentTracker.track("Added Project Skill", project_skill)
conn |> put_status(:created) |> render("show.json-api", data: project_skill)
end
Expand All @@ -44,4 +45,12 @@ defmodule CodeCorpsWeb.ProjectSkillController do
conn |> Conn.assign(:project_skill, project_skill) |> send_resp(:no_content, "")
end
end

@preloads [
:skill
]

def preload(data) do
Repo.preload(data, @preloads)
end
end
2 changes: 1 addition & 1 deletion lib/code_corps_web/controllers/task_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule CodeCorpsWeb.TaskController do
end
end

@preloads [:comments, :github_pull_request, :task_skills, :user_task]
@preloads [:comments, :github_pull_request, :task_skills, :user, [user_task: :user]]

def preload(data) do
timing("TaskController", "preload") do
Expand Down
2 changes: 1 addition & 1 deletion lib/code_corps_web/controllers/task_list_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule CodeCorpsWeb.TaskListController do
end
end

@preloads [:tasks]
@preloads [tasks: [:github_issue, :github_pull_request, :task_skills, :user, [user_task: :user]]]

def preload(data) do
Repo.preload(data, @preloads)
Expand Down
2 changes: 1 addition & 1 deletion lib/code_corps_web/views/project_skill_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ defmodule CodeCorpsWeb.ProjectSkillView do
use JaSerializer.PhoenixView

has_one :project, type: "project", field: :project_id
has_one :skill, type: "skill", field: :skill_id
has_one :skill, serializer: CodeCorpsWeb.SkillView, include: true
end
2 changes: 1 addition & 1 deletion lib/code_corps_web/views/project_user_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ defmodule CodeCorpsWeb.ProjectUserView do
attributes [:role, :inserted_at, :updated_at]

has_one :project, type: "project", field: :project_id
has_one :user, type: "user", field: :user_id
has_one :user, serializer: CodeCorpsWeb.UserSlimView, include: true
end
2 changes: 0 additions & 2 deletions lib/code_corps_web/views/skill_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ defmodule CodeCorpsWeb.SkillView do
use JaSerializer.PhoenixView

attributes [:title, :description, :inserted_at, :updated_at]

has_many :role_skills, serializer: CodeCorpsWeb.RoleSkillView, identifiers: :always
end
21 changes: 21 additions & 0 deletions lib/code_corps_web/views/task_in_list_view.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule CodeCorpsWeb.TaskInListView do
@moduledoc false
use CodeCorpsWeb, :view
use JaSerializer.PhoenixView

def type, do: "task"

attributes [
:archived, :created_at, :number, :order, :status, :title
]

has_one :github_issue, serializer: CodeCorpsWeb.GithubIssueView, include: true
has_one :github_pull_request, serializer: CodeCorpsWeb.GithubPullRequestView, include: true
has_one :github_repo, type: "github-repo", field: :github_repo_id
has_one :project, type: "project", field: :project_id
has_one :task_list, type: "task-list", field: :task_list_id
has_one :user, serializer: CodeCorpsWeb.UserSlimView, include: true
has_one :user_task, serializer: CodeCorpsWeb.UserTaskView, include: true

has_many :task_skills, serializer: CodeCorpsWeb.TaskSkillView, include: true
end
4 changes: 2 additions & 2 deletions lib/code_corps_web/views/task_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ defmodule CodeCorpsWeb.TaskView do
has_one :github_repo, type: "github-repo", field: :github_repo_id
has_one :project, type: "project", field: :project_id
has_one :task_list, type: "task-list", field: :task_list_id
has_one :user, type: "user", field: :user_id
has_one :user_task, serializer: CodeCorpsWeb.UserTaskView, identifiers: :always
has_one :user, serializer: CodeCorpsWeb.UserSlimView, include: true
has_one :user_task, serializer: CodeCorpsWeb.UserTaskView, include: true

has_many :comments, serializer: CodeCorpsWeb.CommentView, identifiers: :always
has_many :task_skills, serializer: CodeCorpsWeb.TaskSkillView, identifiers: :always
Expand Down
57 changes: 57 additions & 0 deletions lib/code_corps_web/views/user_slim_view.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
defmodule CodeCorpsWeb.UserSlimView do
@moduledoc false
alias CodeCorps.Presenters.ImagePresenter

use CodeCorpsWeb, :view
use JaSerializer.PhoenixView

def type, do: "user"

attributes [
:biography, :cloudinary_public_id, :email, :first_name,
:github_avatar_url, :github_id, :github_username, :intercom_user_hash,
:inserted_at, :last_name, :name, :photo_large_url, :photo_thumb_url,
:sign_up_context, :state, :state_transition, :twitter, :username,
:website, :updated_at
]

def photo_large_url(user, _conn), do: ImagePresenter.large(user)

def photo_thumb_url(user, _conn), do: ImagePresenter.thumbnail(user)

@doc """
Returns the user email or an empty string, depending on the user
being rendered is the authenticated user, or some other user.

Users can only see their own emails. Everyone else's are private.
"""
def email(user, %Plug.Conn{assigns: %{current_user: current_user}}) do
if user.id == current_user.id, do: user.email, else: ""
end
def email(_user, _conn), do: ""

@intercom_secret_key Application.get_env(:code_corps, :intercom_identity_secret_key) || "RANDOM_KEY"

def intercom_user_hash(%{id: id}, _conn) when is_number(id) do
id |> Integer.to_string |> do_intercom_user_hash
end
# def intercom_user_hash(_user, _conn), do: nil

defp do_intercom_user_hash(id_string) do
:crypto.hmac(:sha256, @intercom_secret_key, id_string)
|> Base.encode16
|> String.downcase
end

@doc """
Returns the user's full name when both first and last name are present.
Returns the only user's first name or last name when the other is missing,
otherwise returns nil.
"""
def name(%{first_name: first_name, last_name: last_name}, _conn) do
"#{first_name} #{last_name}" |> String.trim |> normalize_name
end

defp normalize_name(name) when name in ["", nil], do: nil
defp normalize_name(name), do: name
end
2 changes: 1 addition & 1 deletion lib/code_corps_web/views/user_task_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ defmodule CodeCorpsWeb.UserTaskView do
use JaSerializer.PhoenixView

has_one :task, type: "task", field: :task_id
has_one :user, type: "user", field: :user_id
has_one :user, serializer: CodeCorpsWeb.UserSlimView, include: true
end