-
Notifications
You must be signed in to change notification settings - Fork 45
feat(rollups): add rollup_contents mapping #519
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
base: main
Are you sure you want to change the base?
Conversation
|
Hi, thanks for the PR! I'll take a look, but I don't know when I'll be able to get to it, since it's Holiday season :)
Yeah, that makes sense.
This is not a problem on its own, there are often multiple rollups that contain a single PR, because if a rollup fails, you create a new one, often before the old one is closed. I don't think that we need to think about that right now.
Also a good point! I'll ignore duplicate PR numbers in rollups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the main query that we will want to execute on the queue page would look something like this:
SELECT
rollup_pr_number, member_pr_number
FROM rollup_member
WHERE repository = $1 AND
rollup_pr_number IN (SELECT number
FROM pull_request AS pr
WHERE pr.repository = $1
AND pr.status IN ('open', 'draft'))
ORDER BY rollup_pr_number;And we get back something like HashMap<PrNum, HashSet<PrNum>>, which maps rollups to their member PRs. Because we assume that there will be only a couple of open rollups, so it seems easier and faster to do it this way, rather than try to find a corresponding rollup for each PR in the queue.
948ac1d to
c1d42a4
Compare
|
Sorry for the long delay (and the force-pushes 👀), the PR should be ready for another review now. Thank you in advance :) |
Kobzol
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, it looks good!
|
I wouldn't actually mind having some basic usage of the new queries in the same PR - it often turns out that a new API will need to be changed once it's actually used 😆 Would you like to take a stab at that? Some ideas:
I think that 3. might be the simplest to implement, and it would be enough to test that the queries that we have here make sense. The rest could be done in follow-up PRs. |
Honestly I agree on implementing the usage of the new queries in this PR. I've been sticking to small PRs mainly to facilitate the reviews and to avoid making it too time consuming for maintainers, as I'll probably do a few mistakes since I just started contributing :) I'd be more than happy to handle it! I'll look into it in this weekend |
|
Yeah ofc small PRs are good in general. On the other hand, I tend to be a bit wary of PRs that just add new functionality without using it, because very often when we start using it we realize that we need to make changes to it anyway 😆 |
…nsert/get logic chore(git): add relevant gitattributes to ensure correct line endings for sqlx files
…ove unnecessary index tweak(rollups): replace access patterns to rollup_member with a single get_nonclosed_rollups operation, to be used within the queue page endpoint logic in the future fix(rollups): add missing test sql file chore(rollups): update migration timestamp
41253eb to
4298378
Compare
…en hovering the row representing a rollup PR
… is to verify the acceptable case of multiple rollups may point to the same member PR
4298378 to
0c5aeee
Compare
Kobzol
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a couple of small nits, but otherwise this looks really awesome! The hover also looks and works great ❤️ Thank you!
| rollup_pr_number BIGINT NOT NULL, | ||
| member_pr_number BIGINT NOT NULL, | ||
| repository TEXT NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| rollup_pr_number BIGINT NOT NULL, | |
| member_pr_number BIGINT NOT NULL, | |
| repository TEXT NOT NULL, | |
| repository TEXT NOT NULL, | |
| rollup_pr_number BIGINT NOT NULL, | |
| member_pr_number BIGINT NOT NULL, |
Just a nit, it's easier to read like this when inspecting the DB state manually :) The migration data SQL file will also need to be updated after this change.
| Ok(()) | ||
| } | ||
|
|
||
| /// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup. | |
| /// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup. | |
| /// Only returns non-closed rollup PRs. |
| AND pr.number = rm.rollup_pr_number | ||
| WHERE rm.repository = $1 | ||
| AND pr.status IN ('open', 'draft') | ||
| ORDER BY rm.rollup_pr_number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ORDER BY rm.rollup_pr_number; |
Doesn't seem to be required, since we store the numbers in a hashmap/hashset anyway? Might help with cache locality for the hashmap, but that's not really needed here, and the DB won't have to sort the rollups.
| tbody.addEventListener("mouseover", handler); | ||
| tbody.addEventListener("mouseleave", clear); | ||
|
|
||
| return () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice that you implemented the event removal, but we don't call it anywhere anyway, so 🤷 I'd just remove it to shorten the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do. One related note: do you think it might be worth to support hovering on mobile devices too? I was thinking of hooking the hover handle to the touchstart event (and clear on touchend).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, not sure, because on click we select the PR - how do you actually distinguish hover and click on mobile? 🤔 If it can be done reliably, then might be useful, but I'd leave it for a future PR :)
| }; | ||
| const handler = (event) => { | ||
| // Reset highlight | ||
| clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| clear() | |
| clear(); |
| } | ||
| let rollupPrMembers = rowElement.dataset.rollupPrMembers; | ||
| if (!rollupPrMembers) { | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return | |
| return; |
| .await | ||
| .context("Cannot create PR")?; | ||
|
|
||
| db.register_rollup_members( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about (many!) follow-up features that we could implement once this PR lands, and I realized that the problem with the missing PR id can be solved very easily. We can simply pre-insert the PR into the DB immediately here:
let pr_db = db.upsert_pull_request(..., pr.into());and then use pr_db.id to record the rollup mapping in the DB.
Since we anyway have to do a JOIN with the PR table when selecting the rollup mapping due to filtering out open PRs, I think that storing the IDs in the mapping would be simpler, after all, would waste less DB space, and would provide proper FK mapping in the DB.
Could you please change it to store (FK to PR table, rollup PR number) in the rollup_member table? Sorry for the late notice 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense! Some questions:
- I assume the fact we perform another upsert from the webhook event received by GitHub for the same PR doesn't matter, as it'd just write the same data. Adding a check to prevent writing PRs that are already in the table in the webhook logic seems pointless - is my assumption correct?
- Wouldn't it make sense to change the member PR number in the same way? I assume we're guaranteed to have an entry in the PR table, as from what I know, rollups can only be created from the queue page, which implies PRs shown there have an entry in the table. Therefore we could use a FK for member PRs too for the same reasons. I think the only tradeoff is that writes would be slightly more expensive, but it shoudn't be a concern with the low amount of writes, and it might help future with future query patterns, if any.
I'm always looking for issues to contribute to (mostly during weekends, when i'm not too tired from working in a startup haha). If you want, write down the ideas in GitHub issues and I'll take care of them!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Yeah, the open PR webhook is not load-bearing. It can in theory race with the rollup handler, but that shouldn't matter much, Postgres will ensure atomicity of the PR creation.
- A very good point! Yeah, I agree. In all cases where we will query this table, the corresponding PRs should already be in the DB. Including when we record the member entries.
Btw, after this change you can remove refresh_prs from rollup tests.
Okay, I will create issues for the features, once this PR lands.

Closes #494.
I wasn't sure whether to use IDs from the pull_request table to represent PRs in the mapping, or just the GitHub PR number - I went with the latter as there would be no record for the rollup at the time of its creation, as that gets populated via GitHub events, if I understood correctly.
I haven't experienced rollups at all as I haven't (yet?) contributed to a project with bors, but I noticed there's no safety check for multiple rollups containing the same PR(s) being opened. I found a related comment here, but I kept it out of this PR to reduce its scope and simplify review. I think such a safety check could be added easily by checking for rollups associated to each candidate PR, and verifying the status of the rollup PR to ignore closed ones. That would still allow one to recreate the same scenario by reopening a previously closed rollup, though.
One thing I'm unsure about is how to handle the error when writing the rollup_contents records in the DB. I think that should only happen either in case of DB connection errors, or if the list of PRs contains duplicates. I assume the former can be propagated to the caller, whereas I'm not sure if the latter is realistic and should be accounted for. I'm thinking we can just ignore the conflicting records in such case - let me know if I should proceed with that.
Edit: sorry, I forgot the migration test files. Will push them tomorrow as soon as possible