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

Add work queue tracking in triagebot DB #1879

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

apiraino
Copy link
Contributor

@apiraino apiraino commented Jan 7, 2025

Rebase of #1786

This implements the new way of assigning pull requests reviews (designed in #1753). When this PR is merged, PRs in rust-lang/rust will be assigned based on user preferences. These can be queried from Zulip (see docs).

If no preferences are set, PRs will be just assigned (like always).

There are multiple points where PRs are assigned (via comment or using the GH UI), I've tried to cover all cases, took some time to test them all. The amount of changes reflect that it is not so easy to catch all spots where this happens. I wish I could make a smaller patch but I think this is an all-or-nothing situation where all cases should be handled at once.

Also modified the zulip triagebot command work show to return the # work queue capacity set by the user. This is helpful in case a PR assignment is rejected. A PR to update the documentation will follow-up after merge of this.

If a PR assignment is rejected we will return a message with some context. Examples:

Failed PR assignment to a user:
screenshot-20240403-104629

Failed self-assignment:
screenshot-20240403-104717

r? @jackh726

Add checks in multiple points when identifying or finding an assignee.

Filter out team members currently not having capacity, return messages
instructing what to do in case the assignment is rejected.

Signed-off-by: apiraino <[email protected]>
@apiraino apiraino force-pushed the assign-prs-based-on-work-queue-take-3 branch 3 times, most recently from 0ac2d52 to d917ccf Compare January 8, 2025 18:07
This check is specifically used when assigning from the Github web UI

Signed-off-by: apiraino <[email protected]>
@apiraino apiraino force-pushed the assign-prs-based-on-work-queue-take-3 branch from d917ccf to 886116c Compare January 8, 2025 18:08
@apiraino apiraino marked this pull request as ready for review January 8, 2025 18:39
FROM review_prefs r
JOIN users on users.user_id=r.user_id
AND username = ANY('{{ {} }}')
AND CARDINALITY(r.assigned_prs) < LEAST(COALESCE(max_assigned_prs,1000000))",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A note about this SQL dance, it is a safeguard against null fields to be able to do a number comparison. CARDINALITY returns the number or array items even when empty, LEAST(COALESCE(...)) returns a number when max_assigned_prs is null.

Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be r.max_assigned_prs? (If not, should it for clarity?)

Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

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

Just double checking, we don't have to do anything fancy with the db before merging, right

FROM review_prefs r
JOIN users on users.user_id=r.user_id
AND username = ANY('{{ {} }}')
AND CARDINALITY(r.assigned_prs) < LEAST(COALESCE(max_assigned_prs,1000000))",
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be r.max_assigned_prs? (If not, should it for clarity?)

usernames
);
let result = db.query(&q, &[]).await.context("Select DB error")?;
let mut candidates: HashSet<String> = HashSet::new();
Copy link
Member

Choose a reason for hiding this comment

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

Nit: you could initialize with the known capacity?

@@ -66,18 +70,60 @@ pub(super) async fn handle_input<'a>(
if matches!(event.action, IssuesAction::Unassigned { .. }) {
delete_pr_from_workqueue(&db_client, assignee.id, event.issue.number)
.await
.context("Failed to remove PR from workqueue")?;
.context("Failed to remove PR from workq ueue")?;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: typo

and there are no other candidates.\n\
Use `r?` to specify someone else to assign.",
User(s) `{}` are either the PR author, already assigned, or on vacation. \
If it's a team, we could not find any candidates.\n\
Copy link
Member

Choose a reason for hiding this comment

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

Not needed, but we could just be smart and use a message tailored to if it was a team or not.

FROM review_prefs r
JOIN users ON users.user_id = r.user_id
WHERE username = $1
AND CARDINALITY(r.assigned_prs) < LEAST(COALESCE(max_assigned_prs,1000000));";
Copy link
Member

Choose a reason for hiding this comment

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

As above, r.max_assigned_prs?

Copy link
Member

Choose a reason for hiding this comment

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

So, I can somewhat see an argument for having the check be done the same as when fetching users, but it's a bit weird that we don't just fetch the number of assigned prs and max assigned prs and check it outside the db.

For consistency, I think let's keep it this way, but put a comment.

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.

2 participants