Skip to content

feat: Slack pairings#553

Open
tarikeshaq wants to merge 14 commits into
masterfrom
donut
Open

feat: Slack pairings#553
tarikeshaq wants to merge 14 commits into
masterfrom
donut

Conversation

@tarikeshaq

@tarikeshaq tarikeshaq commented Oct 12, 2020

Copy link
Copy Markdown

fixes #514 , closes https://github.com/ubclaunchpad/ideas/issues/8

Details

Creates basic donut style matching for Rocket.

What implemented so far:

  • A donut scheduler that currently runs every minute (for debugging purposes, will bump to a reasonable number once this is ready to land)
  • Some initial refactoring to allow the schedulers to have access to the db
  • Slack api calls needed to:
    • Get a slack channel's id by name
    • Create a private conversation given a list of users
  • Basic persistence of pairings in a new pairings table

TODOs before this is ready:

  • Add persistence, to prevent users from getting matched again
  • Add TTL to entries in the Pairings table I can file a follow up for this, we can live without it for now
  • Add tests
    • For slack API calls
    • For persistence
  • Add documentation
    • General documentation for the feature
    • For the new environment variable
    • Documentation for the new pairings table

Where I am currently:

Contemplating if I should add a table for the pairings or if it should be a part of the User model, leaning towards the latter with possibly opening a ticket for the former beyond this pr.
Went with creating a new table 😄 Now working on adding the TTL and making sure edge cases don't explode on us

I'll be updating the above as I go.

@bobheadxi

Copy link
Copy Markdown
Member

Comment thread config/__init__.py Outdated
Comment thread app/scheduler/modules/donut.py Outdated
@chuck-sys

Copy link
Copy Markdown
Collaborator

Contemplating if I should add a table for the pairings or if it should be a part of the User model, leaning towards the latter with possibly opening a ticket for the former beyond this pr.

IMO I think you should go with the former (though the difference in work is pretty significant). Seems less hacky and wouldn't leak too much information (example: /rocket user view can potentially see who you matched with).

And it would set the precedent for similar things in the future.

@bobheadxi bobheadxi removed the ⚒WIP label Oct 12, 2020

@bobheadxi bobheadxi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice progress! 🎉

(also, it seems your commit authors arent attached to your GitHub, not sure if intentional?)

Comment thread app/scheduler/modules/pairing.py Outdated
Comment thread app/scheduler/modules/pairing.py Outdated
def get_job_args(self) -> Dict[str, Any]:
"""Get job configuration arguments for apscheduler."""
return {'trigger': 'cron',
'minute': '*',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this is just temporary for testing, but could also just make this a configuration option! SLACK_PAIRING_FREQUENCY for example

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alrighty made it an env variable as a cron job string... not the cleanest so happy for recommendations!

Comment thread interface/slack.py Outdated
@bobheadxi bobheadxi changed the title [WIP] Adds donut feature to rocket feat: Slack pairings Oct 15, 2020
@codecov

codecov Bot commented Nov 1, 2020

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.52273% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.46%. Comparing base (7b313f1) to head (d2e2b87).
⚠️ Report is 20 commits behind head on master.

Files with missing lines Patch % Lines
app/model/pairing.py 65.00% 14 Missing ⚠️
db/dynamodb.py 57.14% 7 Missing and 2 partials ⚠️
tests/memorydb.py 76.92% 0 Missing and 3 partials ⚠️
interface/slack.py 87.50% 1 Missing and 1 partial ⚠️
app/scheduler/__init__.py 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #553      +/-   ##
==========================================
- Coverage   93.01%   92.46%   -0.55%     
==========================================
  Files          42       44       +2     
  Lines        2420     2589     +169     
  Branches      323      346      +23     
==========================================
+ Hits         2251     2394     +143     
- Misses        110      131      +21     
- Partials       59       64       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tarikeshaq

Copy link
Copy Markdown
Author

OK I got some time to work on this again (after like 20 days 😢) and Added a few tests.

I think this is ready for a round of review so I'll change it from a draft. My next focus will be docs and addressing any feedback that pops up. No rush on the review, we are all busy and this is decently large.

@tarikeshaq tarikeshaq marked this pull request as ready for review November 1, 2020 07:25
@tarikeshaq tarikeshaq requested review from a team as code owners November 1, 2020 07:25

@bobheadxi bobheadxi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic progress, really excited to see this land! Thanks for taking the time to do this ❤️

Comment thread app/model/pairing.py Outdated
Comment thread app/scheduler/modules/pairing.py Outdated
Comment thread app/scheduler/modules/pairing.py Outdated
Comment on lines +43 to +46
self.bot.send_to_channel("Hello! \
You have been matched by Rocket \
please use this channel to get to know each other!",
group_name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should have a configuration option SLACK_PAIRING_TIPS_LINK that can generate a button that links to tips for what to do in a pairing (i.e. "set up video call, talk about x and y") - for Launch Pad this could be a handbook page, for example

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm Can we do this on a follow up or do ya think it's important? Could be a really good first issue for someone!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Can you add all the TODO items for follow-up issues in the PR description as a checklist, to make sure we don't forget?

Comment thread db/dynamodb.py Outdated
Comment thread interface/slack.py Outdated
Comment thread config/__init__.py
@bobheadxi

Copy link
Copy Markdown
Member

rocket-pairing-hd

@chuck-sys chuck-sys left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good job on this! Seems to just need the docs now.

Comment on lines +51 to +53
self.bot.send_to_channel("Hello! \
You have been matched by Rocket \
please use this channel to get to know each other!",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a long string. Can you put it refactor it to be a static member for easy changing?

Comment on lines +58 to +63
Creates pairs of users that haven't been matched before

:param users: A list of slack ids of all users to match

If a pairing cannot be done, then the history of pairings is
purged, and the algorithm is run again.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talk about what kind of algorithm is used here please.

Comment on lines +83 to +84
not_paired = list(
filter(lambda user: user not in already_added, users))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
not_paired = list(
filter(lambda user: user not in already_added, users))
not_paired = [user for user in users if user not in already_added]

Feel free to not use this. I just want everything to fit nicely on one line.

P Y T h O n I C

Comment thread app/model/pairing.py
Comment on lines +25 to +26
self.user1_slack_id = user1_slack_id
self.user2_slack_id = user2_slack_id

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would 3 people models be represented in the database? Or is it intended that 3 people pairings are a one-off?

Comment on lines +85 to +87
# If we have an odd number of people that is not 1
# We put the odd person out in one of the groups
# So we might have a group of 3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# If we have an odd number of people that is not 1
# We put the odd person out in one of the groups
# So we might have a group of 3
# If we have an odd number of people that is not 1,
# or if there is 1 person left unpaired:
# We put the odd person out in one of the groups
# So we might have a group of 3

Comment thread db/dynamodb.py
Comment on lines +322 to +326
table_name = self.CONST.get_table_name(Model)
table = self.ddb.Table(table_name)
table.delete()
table.wait_until_not_exists()
self.__create_table(table_name)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to comment that this is the best way to remove all items from a table, because it makes fewer calls.

Comment thread interface/slack.py

:param users: the list of users to add to the private chat

:raise SlackAPIError if the slack API returned error openning the chat

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:raise SlackAPIError if the slack API returned error openning the chat
:raise SlackAPIError if the slack API returned error opening the chat

Comment thread sample-env
AWS_SECRET_KEY='itsa secret'
AWS_USERS_TABLE='users'
AWS_TEAMS_TABLE='teams'
AWS_PAIRINGS_TABLE='pairings'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to add the optional config options for others to see how it works.


def test_valid_pairing(self):
"""Test the pairing static method is_valid()."""
self.assertTrue(Pairing.is_valid(self.p0))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to test the invalid cases as well!

Comment on lines +38 to +40
assert 'user1' in args
assert 'user2' in args
assert len(args) == 2

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert 'user1' in args
assert 'user2' in args
assert len(args) == 2
self.assertIn('user1', args)
self.assertIn('user2', args)
self.assertEqual(len(args), 2)

There are others.

@bobheadxi

Copy link
Copy Markdown
Member

Nothing that this closes https://github.com/ubclaunchpad/ideas/issues/8 as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

donut-style random pairing for members in a certain channel

3 participants