diff --git a/services/app/apps/codebattle/lib/codebattle/tournament/tournament_result.ex b/services/app/apps/codebattle/lib/codebattle/tournament/tournament_result.ex index 6039141a7..c27e0291c 100644 --- a/services/app/apps/codebattle/lib/codebattle/tournament/tournament_result.ex +++ b/services/app/apps/codebattle/lib/codebattle/tournament/tournament_result.ex @@ -27,6 +27,7 @@ defmodule Codebattle.Tournament.TournamentResult do field(:tournament_id, :integer) field(:user_id, :integer) field(:user_name, :string) + field(:user_lang, :string) end def get_by(tournament_id) do @@ -85,6 +86,7 @@ defmodule Codebattle.Tournament.TournamentResult do (p.player_info->>'result_percent')::numeric AS result_percent, (p.player_info->>'id')::integer AS user_id, (p.player_info->>'name')::text AS user_name, + (p.player_info->>'lang')::text AS user_lang, (p.player_info->>'clan_id')::integer AS clan_id, g.duration_sec, g.tournament_id, @@ -121,6 +123,7 @@ defmodule Codebattle.Tournament.TournamentResult do game_id, user_id, user_name, + user_lang, clan_id, task_id, score, @@ -135,6 +138,7 @@ defmodule Codebattle.Tournament.TournamentResult do game_id, user_id, user_name, + user_lang, clan_id, task_id, score, @@ -159,6 +163,7 @@ defmodule Codebattle.Tournament.TournamentResult do (p.player_info->>'result_percent')::numeric AS result_percent, (p.player_info->>'id')::integer AS user_id, (p.player_info->>'name')::text AS user_name, + (p.player_info->>'lang')::text AS user_lang, (p.player_info->>'clan_id')::integer AS clan_id, g.duration_sec, g.level, @@ -183,6 +188,7 @@ defmodule Codebattle.Tournament.TournamentResult do game_id, user_id, user_name, + user_lang, clan_id, task_id, score, @@ -197,6 +203,7 @@ defmodule Codebattle.Tournament.TournamentResult do game_id, user_id, user_name, + user_lang, clan_id, task_id, score, @@ -229,6 +236,7 @@ defmodule Codebattle.Tournament.TournamentResult do select: %{ user_id: tr.user_id, user_name: max(tr.user_name), + user_lang: max(tr.user_lang), opponent_id: tr2.user_id, round_position: tr.round_position, score: coalesce(sum(tr.score), 0), @@ -242,6 +250,7 @@ defmodule Codebattle.Tournament.TournamentResult do tr2.result_percent ), opponent_name: max(tr2.user_name), + opponent_lang: max(tr2.user_lang), opponent_clan_id: max(tr2.clan_id) } ) @@ -280,13 +289,14 @@ defmodule Codebattle.Tournament.TournamentResult do select: %{ id: r.user_id, name: r.user_name, + lang: r.user_lang, clan_id: c.id, clan: c.name, score: sum(r.score), place: over(row_number(), :overall_partition) }, where: r.tournament_id == ^tournament.id, - group_by: [r.user_id, r.user_name, c.id], + group_by: [r.user_id, r.user_name, r.user_lang, c.id], order_by: [desc: sum(r.score), asc: sum(r.duration_sec)], windows: [overall_partition: [order_by: [desc: sum(r.score), asc: sum(r.duration_sec)]]] ) @@ -306,13 +316,14 @@ defmodule Codebattle.Tournament.TournamentResult do select: %{ id: r.user_id, name: r.user_name, + lang: r.user_lang, clan_id: c.id, clan: c.name, score: sum(r.score), place: over(row_number(), :overall_partition) }, where: r.tournament_id == ^tournament.id, - group_by: [r.user_id, r.user_name, c.id], + group_by: [r.user_id, r.user_name, r.user_lang, c.id], order_by: [desc: sum(r.score), asc: sum(r.duration_sec)], windows: [overall_partition: [order_by: [desc: sum(r.score), asc: sum(r.duration_sec)]]] ) @@ -357,6 +368,7 @@ defmodule Codebattle.Tournament.TournamentResult do tr.clan_id, tr.user_id, tr.user_name, + tr.user_lang, SUM(tr.score) AS total_score, SUM(tr.duration_sec) AS total_duration_sec, SUM(CASE WHEN tr.result_percent = 100.0 THEN 1 ELSE 0 END) AS wins_count @@ -365,13 +377,14 @@ defmodule Codebattle.Tournament.TournamentResult do WHERE tr.tournament_id = #{tournament.id} GROUP BY - tr.clan_id, tr.user_id, tr.user_name + tr.clan_id, tr.user_id, tr.user_name, tr.user_lang ), TopPlayers AS ( SELECT pa.clan_id, pa.user_id, pa.user_name, + pa.user_lang, pa.total_score, pa.total_duration_sec, pa.wins_count, @@ -384,6 +397,7 @@ defmodule Codebattle.Tournament.TournamentResult do tp.clan_id, tp.user_id, tp.user_name, + tp.user_lang, tp.total_score, tp.total_duration_sec, tp.wins_count @@ -410,6 +424,7 @@ defmodule Codebattle.Tournament.TournamentResult do tp.clan_id, tp.user_id, tp.user_name, + tp.user_lang, tp.total_score, tp.total_duration_sec, tp.wins_count, @@ -425,6 +440,7 @@ defmodule Codebattle.Tournament.TournamentResult do c.long_name AS clan_long_name, t.user_id, t.user_name, + t.user_lang, t.total_score, t.total_duration_sec, t.wins_count, @@ -590,7 +606,8 @@ defmodule Codebattle.Tournament.TournamentResult do game_id: r.game_id, score: r.score, user_id: r.user_id, - user_name: max(r.user_name) + user_name: max(r.user_name), + user_lang: max(r.user_lang) } ) diff --git a/services/app/apps/codebattle/lib/codebattle/tournament/tournament_user_result.ex b/services/app/apps/codebattle/lib/codebattle/tournament/tournament_user_result.ex index a6f338e59..113b8ebcc 100644 --- a/services/app/apps/codebattle/lib/codebattle/tournament/tournament_user_result.ex +++ b/services/app/apps/codebattle/lib/codebattle/tournament/tournament_user_result.ex @@ -11,18 +11,19 @@ defmodule Codebattle.Tournament.TournamentUserResult do @type t :: %__MODULE__{} schema "tournament_user_results" do - field(:user_id, :integer) + field(:avg_result_percent, :decimal) field(:clan_id, :integer) - field(:user_name, :string) + field(:games_count, :integer, default: 0) + field(:is_cheater, :boolean, default: false) + field(:place, :integer, default: 0) + field(:points, :integer, default: 0) field(:score, :integer, default: 0) + field(:total_time, :integer, default: 0) field(:tournament_id, :integer) - field(:points, :integer, default: 0) - field(:place, :integer, default: 0) - field(:games_count, :integer, default: 0) + field(:user_id, :integer) + field(:user_name, :string) + field(:user_lang, :string) field(:wins_count, :integer, default: 0) - field(:total_time, :integer, default: 0) - field(:is_cheater, :boolean, default: false) - field(:avg_result_percent, :decimal) timestamps(updated_at: false) end @@ -58,6 +59,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do tr.user_id, tr.clan_id, tr.user_name, + tr.user_lang, SUM(tr.score)::integer AS score, COUNT(*)::integer AS games_count, SUM(CASE WHEN tr.result_percent = 100.0 THEN 1 ELSE 0 END)::integer AS wins_count, @@ -66,7 +68,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do AVG(tr.result_percent)::numeric(5,1) AS avg_result_percent FROM tournament_results tr WHERE tr.tournament_id = #{tournament.id} - GROUP BY tr.tournament_id, tr.user_id, tr.clan_id, tr.user_name + GROUP BY tr.tournament_id, tr.user_id, tr.clan_id, tr.user_name, tr.user_lang ), ranked_results AS ( SELECT @@ -74,6 +76,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do ar.user_id, ar.clan_id, ar.user_name, + ar.user_lang, ar.score, ar.games_count, ar.wins_count, @@ -91,6 +94,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do rr.user_id, rr.clan_id, rr.user_name, + rr.user_lang, rr.score, rr.place, rr.games_count, @@ -107,6 +111,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do user_id, clan_id, user_name, + user_lang, score, points, place, @@ -122,6 +127,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do user_id, clan_id, user_name, + user_lang, score, points, place, @@ -135,6 +141,7 @@ defmodule Codebattle.Tournament.TournamentUserResult do ON CONFLICT (tournament_id, user_id) DO UPDATE SET user_name = EXCLUDED.user_name, + user_lang = EXCLUDED.user_lang, score = EXCLUDED.score, points = EXCLUDED.points, place = EXCLUDED.place, diff --git a/services/app/apps/codebattle/lib/codebattle/users_points_and_rank_update_server.ex b/services/app/apps/codebattle/lib/codebattle/users_points_and_rank_update_server.ex index a91e1c000..f76369ed1 100644 --- a/services/app/apps/codebattle/lib/codebattle/users_points_and_rank_update_server.ex +++ b/services/app/apps/codebattle/lib/codebattle/users_points_and_rank_update_server.ex @@ -18,7 +18,7 @@ defmodule Codebattle.UsersPointsAndRankUpdateServer do # SERVER def init(_) do - Process.send_after(self(), :subscribe, to_timeout(second: 15)) + Process.send_after(self(), :subscribe, 0) Process.send_after(self(), :work, to_timeout(minute: 5)) Logger.debug("Start UsersPointsServer") @@ -32,12 +32,7 @@ defmodule Codebattle.UsersPointsAndRankUpdateServer do end def handle_info(:subscribe, state) do - if FunWithFlags.enabled?(:skip_user_points_server) do - :noop - else - Codebattle.PubSub.subscribe("tournaments") - end - + Codebattle.PubSub.subscribe("tournaments") {:noreply, state} end diff --git a/services/app/apps/codebattle/priv/repo/migrations/20251016162159_add_user_lang_to_tournament_results.exs b/services/app/apps/codebattle/priv/repo/migrations/20251016162159_add_user_lang_to_tournament_results.exs new file mode 100644 index 000000000..2bda4a11c --- /dev/null +++ b/services/app/apps/codebattle/priv/repo/migrations/20251016162159_add_user_lang_to_tournament_results.exs @@ -0,0 +1,13 @@ +defmodule Codebattle.Repo.Migrations.AddUserLangToTournamentResults do + use Ecto.Migration + + def change do + alter table(:tournament_user_results) do + add(:user_lang, :string) + end + + alter table(:tournament_results) do + add(:user_lang, :string) + end + end +end diff --git a/services/app/apps/codebattle/test/codebattle/tournament/entire/swiss_grand_slam_test.exs b/services/app/apps/codebattle/test/codebattle/tournament/entire/swiss_grand_slam_test.exs index 3dd97f52d..4fe1f150e 100644 --- a/services/app/apps/codebattle/test/codebattle/tournament/entire/swiss_grand_slam_test.exs +++ b/services/app/apps/codebattle/test/codebattle/tournament/entire/swiss_grand_slam_test.exs @@ -13,7 +13,6 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do @decimal100 Decimal.new("100.0") @decimal0 Decimal.new("0.0") - @tag :skip test "works with player who solved all tasks" do [%{id: t1_id}, %{id: t2_id}, %{id: t3_id}] = insert_list(3, :task, level: "easy") insert(:task_pack, name: "tp", task_ids: [t1_id, t2_id, t3_id]) @@ -290,7 +289,11 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do assert Process.info(self(), :message_queue_len) == {:message_queue_len, 0} + :timer.sleep(100) tournament = %{id: tournament_id} = Tournament.Context.get(tournament.id) + + assert tournament.state == "finished" + matches = get_matches(tournament) assert Enum.count(matches) == 3 @@ -309,6 +312,7 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do task_id: ^t1_id, tournament_id: ^tournament_id, user_id: ^u1_id, + user_lang: "js", user_name: "1" }, %{ @@ -374,7 +378,8 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do task_id: ^t3_id, tournament_id: ^tournament_id, user_id: ^u2_id, - user_name: "2" + user_name: "2", + user_lang: "js" } ] = TournamentResult |> Repo.all() |> Enum.sort_by(&{&1.user_id, &1.task_id}) @@ -392,6 +397,7 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do tournament_id: ^tournament_id, user_id: ^u1_id, user_name: "1", + user_lang: "js", wins_count: 3 }, %{ @@ -407,11 +413,12 @@ defmodule Codebattle.Tournament.Entire.SwissGrandSlamTest do tournament_id: ^tournament_id, user_id: ^u2_id, user_name: "2", + user_lang: "js", wins_count: 0 } ] = TournamentUserResult |> Repo.all() |> Enum.sort_by(& &1.user_id) - :timer.sleep(to_timeout(second: 2)) + :timer.sleep(to_timeout(second: 5)) assert %{rating: 1023, rank: 1, points: 2048} = Repo.get(User, u1_id) assert %{rating: 977, rank: 2, points: 1024} = Repo.get(User, u2_id) end