Skip to content

Commit e0dab0a

Browse files
committed
Refactor user syncing into separate step and clean up some queries
1 parent e426867 commit e0dab0a

File tree

10 files changed

+82
-41
lines changed

10 files changed

+82
-41
lines changed

config/dev.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ config :code_corps, CodeCorpsWeb.Endpoint,
2626
]
2727

2828
# Do not include metadata nor timestamps in development logs
29-
config :logger, :console, format: "[$level] $message\n"
29+
config :logger,
30+
:console, format: "[$level] $message\n"
3031

3132
# Set a higher stacktrace during development. Avoid configuring such
3233
# in production as building large stacktraces may be expensive.

lib/code_corps/github/sync/comment/comment/comment.ex

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ defmodule CodeCorps.GitHub.Sync.Comment.Comment do
2424
User
2525
}
2626
alias CodeCorps.GitHub.Sync.Comment.Comment.Changeset, as: CommentChangeset
27-
alias CodeCorps.GitHub.Sync.User.User, as: UserSyncer
2827
alias Ecto.Changeset
2928

3029
@type outcome :: {:ok, list(Comment.t)} |
@@ -52,16 +51,15 @@ defmodule CodeCorps.GitHub.Sync.Comment.Comment do
5251
github_repo: %GithubRepo{
5352
github_comments: github_comments
5453
}
55-
} = project_github_repo |> Repo.preload([:project, github_repo: [github_comments: [:github_issue, :github_user]]])
54+
} = project_github_repo |> Repo.preload([:project, github_repo: [github_comments: [:github_issue, github_user: [:user]]]])
5655

5756
github_comments
5857
|> Enum.map(&find_or_create_comment(&1, project_github_repo))
5958
|> ResultAggregator.aggregate
6059
end
6160

62-
defp find_or_create_comment(%GithubComment{github_user: %GithubUser{} = github_user} = github_comment, %ProjectGithubRepo{} = project_github_repo) do
63-
with {:ok, %User{} = user} <- UserSyncer.create_or_update_user(github_user),
64-
%Task{} = task <- find_task(github_comment, project_github_repo),
61+
defp find_or_create_comment(%GithubComment{github_user: %GithubUser{user: %User{} = user}} = github_comment, %ProjectGithubRepo{} = project_github_repo) do
62+
with %Task{} = task <- find_task(github_comment, project_github_repo),
6563
{:ok, %Comment{} = comment} <- sync(task, github_comment, user)
6664
do
6765
{:ok, comment}
@@ -85,7 +83,7 @@ defmodule CodeCorps.GitHub.Sync.Comment.Comment do
8583
task
8684
|> find_or_init_comment(github_comment)
8785
|> CommentChangeset.build_changeset(github_comment, task, user)
88-
|> commit()
86+
|> Repo.insert_or_update()
8987
end
9088

9189
@doc ~S"""
@@ -110,7 +108,7 @@ defmodule CodeCorps.GitHub.Sync.Comment.Comment do
110108
task
111109
|> find_or_init_comment(payload)
112110
|> CommentChangeset.build_changeset(payload, github_comment, task, user)
113-
|> commit()
111+
|> Repo.insert_or_update()
114112
end
115113

116114
@spec find_or_init_comment(Task.t, Comment.t) :: Comment.t
@@ -136,8 +134,4 @@ defmodule CodeCorps.GitHub.Sync.Comment.Comment do
136134
%Comment{} = comment -> comment
137135
end
138136
end
139-
140-
@spec commit(Changeset.t) :: {:ok, Comment.t} | {:error, Changeset.t}
141-
defp commit(%Changeset{data: %Comment{id: nil}} = changeset), do: changeset |> Repo.insert
142-
defp commit(%Changeset{} = changeset), do: changeset |> Repo.update
143137
end
Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule CodeCorps.GitHub.Sync.Issue.Task do
2+
import Ecto.Query
3+
24
alias CodeCorps.{
35
GithubIssue,
46
GithubRepo,
@@ -10,7 +12,6 @@ defmodule CodeCorps.GitHub.Sync.Issue.Task do
1012
Repo
1113
}
1214
alias CodeCorps.GitHub.Sync.Issue.Task.Changeset, as: TaskChangeset
13-
alias CodeCorps.GitHub.Sync.User.User, as: UserSyncer
1415
alias Ecto.Changeset
1516

1617
@type outcome :: {:ok, list(Task.t)} |
@@ -39,58 +40,41 @@ defmodule CodeCorps.GitHub.Sync.Issue.Task do
3940
github_repo: %GithubRepo{
4041
github_issues: github_issues
4142
}
42-
} = project_github_repo
43+
} = project_github_repo |> Repo.preload([:project, github_repo: [github_issues: [github_user: [:user]]]])
4344

4445
github_issues
4546
|> Enum.map(&find_or_create_task(&1, project_github_repo))
4647
|> ResultAggregator.aggregate
4748
end
4849

49-
defp find_or_create_task(%GithubIssue{github_user: %GithubUser{} = github_user} = github_issue, %ProjectGithubRepo{} = project_github_repo) do
50-
with {:ok, %User{} = user} <- UserSyncer.create_or_update_user(github_user),
51-
{:ok, %Task{} = task} <- sync(github_issue, project_github_repo, user)
52-
do
53-
{:ok, task}
54-
else
55-
{:error, error} -> {:error, error}
56-
end
50+
defp find_or_create_task(%GithubIssue{github_user: %GithubUser{user: %User{} = user}} = github_issue, %ProjectGithubRepo{} = project_github_repo) do
51+
sync(github_issue, project_github_repo, user)
5752
end
5853

5954
@spec sync(GithubIssue.t, ProjectGithubRepo.t, User.t) :: {:ok, ProjectGithubRepo.t} | {:error, Changeset.t}
6055
defp sync(%GithubIssue{} = github_issue, %ProjectGithubRepo{} = project_github_repo, %User{} = user) do
6156
project_github_repo
6257
|> find_or_init_task(github_issue)
6358
|> TaskChangeset.build_changeset(github_issue, project_github_repo, user)
64-
|> commit()
59+
|> Repo.insert_or_update()
6560
end
6661

6762
@spec sync(GithubIssue.t, ProjectGithubRepo.t, User.t, map) :: {:ok, ProjectGithubRepo.t} | {:error, Changeset.t}
6863
defp sync(%GithubIssue{} = github_issue, %ProjectGithubRepo{} = project_github_repo, %User{} = user, %{} = payload) do
6964
project_github_repo
7065
|> find_or_init_task(github_issue)
7166
|> TaskChangeset.build_changeset(payload, github_issue, project_github_repo, user)
72-
|> commit()
67+
|> Repo.insert_or_update()
7368
end
7469

7570
@spec find_or_init_task(ProjectGithubRepo.t, GithubIssue.t) :: Task.t
7671
defp find_or_init_task(
77-
%ProjectGithubRepo{project_id: project_id, github_repo_id: github_repo_id},
72+
%ProjectGithubRepo{project_id: project_id},
7873
%GithubIssue{id: github_issue_id}
7974
) do
80-
81-
query_params = [
82-
github_issue_id: github_issue_id,
83-
github_repo_id: github_repo_id,
84-
project_id: project_id
85-
]
86-
87-
case Task |> Repo.get_by(query_params) do
75+
case Task |> Repo.get_by(github_issue_id: github_issue_id, project_id: project_id) do
8876
nil -> %Task{}
8977
%Task{} = task -> task
9078
end
9179
end
92-
93-
@spec commit(Changeset.t) :: {:ok, Task.t} | {:error, Changeset.t}
94-
defp commit(%Changeset{data: %Task{id: nil}} = changeset), do: changeset |> Repo.insert
95-
defp commit(%Changeset{} = changeset), do: changeset |> Repo.update
9680
end

lib/code_corps/github/sync/sync.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ defmodule CodeCorps.GitHub.Sync do
123123
|> Repo.update
124124
end
125125

126-
127126
@count_fields [:syncing_comments_count, :syncing_issues_count, :syncing_pull_requests_count]
128127

129128
defp build_sync_params(sync_state, opts) do
@@ -174,6 +173,8 @@ defmodule CodeCorps.GitHub.Sync do
174173
with {:ok, project_github_repo} <- project_github_repo |> mark_project_repo("syncing_github_repo"),
175174
{:ok, %GithubRepo{sync_state: "receiving_webhooks"}} <- repo |> sync_repo(),
176175
project_github_repo <- Repo.get(ProjectGithubRepo, project_github_repo.id) |> preload_project_github_repo(),
176+
{:ok, project_github_repo} <- project_github_repo |> mark_project_repo("syncing_users"),
177+
{:ok, _users} <- project_github_repo |> Sync.User.User.sync_project_github_repo() |> sync_step(:sync_users),
177178
{:ok, project_github_repo} <- project_github_repo |> mark_project_repo("syncing_tasks"),
178179
{:ok, _tasks} <- project_github_repo |> Sync.Issue.Task.sync_project_github_repo() |> sync_step(:sync_tasks),
179180
{:ok, project_github_repo} <- project_github_repo |> mark_project_repo("syncing_comments"),
@@ -183,14 +184,15 @@ defmodule CodeCorps.GitHub.Sync do
183184
{:ok, project_github_repo}
184185
else
185186
{:ok, %GithubRepo{}} -> project_github_repo |> mark_project_repo("errored_syncing_github_repo")
187+
{:error, :sync_users} -> repo |> mark_project_repo("errored_syncing_users")
186188
{:error, :sync_tasks} -> repo |> mark_project_repo("errored_syncing_tasks")
187189
{:error, :sync_comments} -> repo |> mark_project_repo("errored_syncing_comments")
188190
end
189191
end
190192

191193
defp preload_project_github_repo(%ProjectGithubRepo{} = project_github_repo) do
192194
project_github_repo
193-
|> Repo.preload([:project, github_repo: [:github_app_installation, [github_issues: [:github_comments, :github_user]]]])
195+
|> Repo.preload([:project, github_repo: [:github_app_installation, [github_comments: [:github_issue, :github_user], github_issues: [:github_comments, :github_user]]]])
194196
end
195197

196198
@doc false

lib/code_corps/github/sync/user/user.ex

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,56 @@ defmodule CodeCorps.GitHub.Sync.User.User do
33
In charge of finding or creating a `User` given a `GithubUser`.
44
"""
55

6+
import Ecto.Query
7+
68
alias CodeCorps.{
79
Accounts,
10+
GithubComment,
11+
GithubIssue,
12+
GithubRepo,
813
GithubUser,
14+
GitHub.Utils.ResultAggregator,
15+
ProjectGithubRepo,
916
Repo,
1017
User
1118
}
1219

20+
def sync_project_github_repo(%ProjectGithubRepo{github_repo: %GithubRepo{} = _} = project_github_repo) do
21+
%ProjectGithubRepo{
22+
github_repo: %GithubRepo{
23+
github_comments: github_comments,
24+
github_issues: github_issues
25+
}
26+
} = project_github_repo
27+
28+
comment_users = find_users_for_comments(github_comments)
29+
issue_users = find_users_for_issues(github_issues)
30+
31+
comment_users
32+
|> Enum.concat(issue_users)
33+
|> Enum.uniq()
34+
|> Enum.map(&create_or_update_user/1)
35+
|> ResultAggregator.aggregate
36+
end
37+
38+
defp find_users_for_comments(github_comments) do
39+
github_comment_ids = Enum.map(github_comments, fn c -> c.id end)
40+
query = from gu in GithubUser,
41+
distinct: gu.id,
42+
join: gc in GithubComment, on: gu.id == gc.github_user_id, where: gc.id in ^github_comment_ids
43+
44+
query |> Repo.all
45+
end
46+
47+
defp find_users_for_issues(github_issues) do
48+
github_issue_ids = Enum.map(github_issues, fn i -> i.id end)
49+
query = from gu in GithubUser,
50+
distinct: gu.id,
51+
join: gi in GithubIssue, on: gu.id == gi.github_user_id, where: gi.id in ^github_issue_ids
52+
53+
query |> Repo.all
54+
end
55+
1356
@doc ~S"""
1457
Creates or updates a `User` given a `GithubUser`.
1558
"""

lib/code_corps/model/github_user.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ defmodule CodeCorps.GithubUser do
99
field :type, :string
1010
field :username, :string
1111

12+
has_one :user, CodeCorps.User
13+
1214
timestamps()
1315
end
1416

lib/code_corps/model/project_github_repo.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ defmodule CodeCorps.ProjectGithubRepo do
4242
~w{
4343
unsynced
4444
syncing_github_repo errored_syncing_github_repo
45+
syncing_users errored_syncing_users
4546
syncing_tasks errored_syncing_tasks
4647
syncing_comments errored_syncing_comments
4748
synced

lib/code_corps/model/task.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule CodeCorps.Task do
33

44
import EctoOrdered
55

6-
alias CodeCorps.{Task, Services.MarkdownRendererService}
6+
alias CodeCorps.{Repo, Services.MarkdownRendererService, Task}
77
alias Ecto.Changeset
88

99
@type t :: %__MODULE__{}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule CodeCorps.Repo.Migrations.AddIndexesForSyncing do
2+
use Ecto.Migration
3+
4+
def change do
5+
create index(:tasks, [:github_issue_id, :project_id])
6+
end
7+
end

priv/repo/structure.sql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3114,6 +3114,13 @@ CREATE INDEX tasks_archived_index ON tasks USING btree (archived);
31143114
CREATE INDEX tasks_github_issue_id_index ON tasks USING btree (github_issue_id);
31153115

31163116

3117+
--
3118+
-- Name: tasks_github_issue_id_project_id_index; Type: INDEX; Schema: public; Owner: -
3119+
--
3120+
3121+
CREATE INDEX tasks_github_issue_id_project_id_index ON tasks USING btree (github_issue_id, project_id);
3122+
3123+
31173124
--
31183125
-- Name: tasks_github_repo_id_index; Type: INDEX; Schema: public; Owner: -
31193126
--
@@ -3837,5 +3844,5 @@ ALTER TABLE ONLY users
38373844
-- PostgreSQL database dump complete
38383845
--
38393846

3840-
INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552), (20170313130611), (20170318032449), (20170318082740), (20170324194827), (20170424215355), (20170501225441), (20170505224222), (20170526095401), (20170602000208), (20170622205732), (20170626231059), (20170628092119), (20170628213609), (20170629183404), (20170630140136), (20170706132431), (20170707213648), (20170711122252), (20170717092127), (20170725060612), (20170727052644), (20170731130121), (20170814131722), (20170913114958), (20170921014405), (20170925214512), (20170925230419), (20170926134646), (20170927100300), (20170928234412), (20171003134956), (20171003225853), (20171006063358), (20171006161407), (20171012215106), (20171012221231), (20171016125229), (20171016125516), (20171016223356), (20171016235656), (20171017235433), (20171019191035), (20171025184225), (20171026010933), (20171027061833), (20171028011642), (20171028173508), (20171030182857), (20171031232023), (20171031234356), (20171101023309);
3847+
INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552), (20170313130611), (20170318032449), (20170318082740), (20170324194827), (20170424215355), (20170501225441), (20170505224222), (20170526095401), (20170602000208), (20170622205732), (20170626231059), (20170628092119), (20170628213609), (20170629183404), (20170630140136), (20170706132431), (20170707213648), (20170711122252), (20170717092127), (20170725060612), (20170727052644), (20170731130121), (20170814131722), (20170913114958), (20170921014405), (20170925214512), (20170925230419), (20170926134646), (20170927100300), (20170928234412), (20171003134956), (20171003225853), (20171006063358), (20171006161407), (20171012215106), (20171012221231), (20171016125229), (20171016125516), (20171016223356), (20171016235656), (20171017235433), (20171019191035), (20171025184225), (20171026010933), (20171027061833), (20171028011642), (20171028173508), (20171030182857), (20171031232023), (20171031234356), (20171101023309), (20171104013543);
38413848

0 commit comments

Comments
 (0)