-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce matchmaking groups as a replacement to yaml exclusivity This is a pretty large change and some of it was to migrate tests for classes that were touched. The primary aspects to this change include a UI piece for creating matchmaking groups and refactoring the group collection to incorporate the database groups with the yaml config groups. Also, there was a HACK to prevent segfault in test & development with pg See more information [here](ged/ruby-pg#538). --------- Co-authored-by: Ali Ibrahim <[email protected]>
- Loading branch information
Showing
53 changed files
with
1,121 additions
and
583 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,4 +37,5 @@ group :test do | |
gem "mocktail" | ||
gem "rspec" | ||
gem "rspec-rails" | ||
gem "timecop" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
class MatchmakingGroupsController < ApplicationController | ||
def index | ||
@groups = CollectGroups.new.call.sort_by { |group| [group.readonly? ? 0 : 1, group.name] } | ||
end | ||
|
||
def new | ||
@group = MatchmakingGroup.new | ||
end | ||
|
||
def create | ||
if MatchmakingGroup.name_exists?(group_params[:name]) | ||
flash[:error] = "Group already exists" | ||
else | ||
MatchmakingGroup.create(group_params.merge(slack_user_id: @current_user.slack_user_id)) | ||
flash[:notice] = "Group created" | ||
end | ||
|
||
redirect_to matchmaking_groups_path | ||
end | ||
|
||
def edit | ||
@group = MatchmakingGroup.find_by(id: params[:id]) | ||
redirect_to matchmaking_groups_path if @group.nil? | ||
end | ||
|
||
def update | ||
@group = MatchmakingGroup.find_by(id: params[:id]) | ||
|
||
if @group.name != group_params[:name] && MatchmakingGroup.name_exists?(group_params[:name]) | ||
flash[:error] = "Other group already exists with that name" | ||
else | ||
@group = MatchmakingGroup.find_by(id: params[:id]) | ||
@group.update(group_params) | ||
|
||
flash[:notice] = "Group updated" | ||
end | ||
redirect_to matchmaking_groups_path | ||
end | ||
|
||
def destroy | ||
@group = MatchmakingGroup.find_by(id: params[:id]) | ||
@group.destroy if @group.present? | ||
redirect_to matchmaking_groups_path | ||
end | ||
|
||
private | ||
|
||
def group_params | ||
params.require(:matchmaking_group) | ||
.permit(:name, :slack_channel_name, :schedule, :target_size, :is_active) | ||
.tap do |hash| | ||
hash[:name] = hash[:name].strip | ||
end | ||
end | ||
end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
class MatchmakingGroup < ApplicationRecord | ||
validate :name_not_in_config | ||
validates :name, uniqueness: true | ||
|
||
def self.name_exists?(name) | ||
Rails.application.config.x.matchmaking.to_h.transform_keys(&:to_s).key?(name) || exists?(name: name) | ||
end | ||
|
||
def active? | ||
is_active | ||
end | ||
|
||
def active | ||
is_active | ||
end | ||
|
||
def active=(value) | ||
self.is_active = value | ||
end | ||
|
||
def channel | ||
slack_channel_name | ||
end | ||
|
||
def channel=(value) | ||
self.slack_channel_name = value | ||
end | ||
|
||
def size | ||
target_size | ||
end | ||
|
||
def size=(value) | ||
self.target_size = value | ||
end | ||
|
||
private | ||
|
||
def name_not_in_config | ||
if Rails.application.config.x.matchmaking.to_h.key?(name.intern) | ||
errors.add(:name, "cannot be the same as a key in the matchmaking config") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
class CollectGroups | ||
def initialize | ||
@config = Rails.application.config.x.matchmaking | ||
end | ||
|
||
def call | ||
extra_groups = MatchmakingGroup.all | ||
readonly_groups + extra_groups | ||
end | ||
|
||
private | ||
|
||
def readonly_groups | ||
@config.to_h.map do |name, group_config| | ||
normalized = group_config.to_h.transform_keys do |key| | ||
next :target_size if key.intern == :size | ||
next :is_active if key.intern == :active | ||
next :slack_channel_name if key.intern == :channel | ||
key | ||
end | ||
|
||
group = MatchmakingGroup.new(normalized.merge(name: name)) | ||
group.define_singleton_method(:readonly?) { true } | ||
group | ||
end | ||
end | ||
end |
2 changes: 1 addition & 1 deletion
2
.../mailer/builds_grouping_mailer_message.rb → ...ices/mailer/build_group_mailer_message.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,11 @@ | ||
module Matchmaking | ||
class ChooseStrategy | ||
def initialize(config: nil) | ||
@config = config || Rails.application.config.x.matchmaking | ||
end | ||
|
||
def call(grouping) | ||
group_config = @config.send(grouping.intern) | ||
return nil unless group_config&.active | ||
def call(group) | ||
return nil unless group&.active? | ||
|
||
return Strategies::PairByFewestEncounters.new if group_config.size == 2 | ||
return Strategies::PairByFewestEncounters.new if group.target_size == 2 | ||
|
||
Strategies::ArrangeGroupsGenetically.new(target_group_size: group_config.size) | ||
Strategies::ArrangeGroupsGenetically.new(target_group_size: group.target_size) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Matchmaking | ||
module Errors | ||
class ChannelNotFound < StandardError | ||
def initialize(group_name, channel_name) | ||
super("No channel found with name '#{channel_name}' for grouping '#{group_name}'") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Matchmaking | ||
module Errors | ||
class NoConfiguredChannel < StandardError | ||
def initialize(group_name) | ||
super("No configured channel for grouping '#{group_name}'") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
module Matchmaking | ||
class EstablishMatchesForGroup | ||
def initialize | ||
@loads_slack_channels = Slack::LoadsSlackChannels.new | ||
@loads_slack_channel_members = Slack::LoadsSlackChannelMembers.new | ||
@match_participants = Matchmaking::MatchParticipants.new | ||
end | ||
|
||
def call(group) | ||
ensure_channel_configured(group) | ||
|
||
channel = fetch_slack_channel(group.slack_channel_name) | ||
ensure_channel_found(channel, group) | ||
|
||
participants = @loads_slack_channel_members.call(channel: channel.id) | ||
|
||
matches = @match_participants.call(participants, group) | ||
matches.each do |match| | ||
HistoricalMatch.create( | ||
members: match, | ||
grouping: group.name, | ||
matched_on: Date.today, | ||
pending_notifications: [ | ||
PendingNotification.create(strategy: "email"), | ||
PendingNotification.create(strategy: "slack") | ||
] | ||
) | ||
end | ||
rescue => e | ||
ReportsError.report(e) | ||
end | ||
|
||
private | ||
|
||
def ensure_channel_configured(group) | ||
raise Errors::NoConfiguredChannel.new(group.name) unless group.slack_channel_name | ||
end | ||
|
||
def ensure_channel_found(channel, group) | ||
raise Errors::ChannelNotFound.new(group.slack_channel_name, group.name) unless channel | ||
end | ||
|
||
def fetch_slack_channel(channel_name) | ||
@loads_slack_channels.call(types: "public_channel").find { |channel| | ||
channel.name_normalized == channel_name | ||
} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.