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

[HNT-405] Remove blocked topics from sections #791

Merged
merged 3 commits into from
Feb 18, 2025

Conversation

mmiermans
Copy link
Collaborator

@mmiermans mmiermans commented Feb 12, 2025

References

JIRA: HNT-405

Description

If a user blocks a section using the Follow/Block feature (e.g. Food, Politics), we remove recommendations with those topics from sections, including 'Popular Today'.

PR Review Checklist

Put an x in the boxes that apply

  • This PR conforms to the Contribution Guidelines
  • The PR title starts with the JIRA issue reference, format example [DISCO-####], and has the same title (if applicable)
  • [load test: (abort|skip|warn)] keywords are applied to the last commit message (if applicable)
  • Documentation has been updated (if applicable)
  • Functional and performance test coverage has been expanded and maintained (if applicable)

@mmiermans mmiermans requested a review from jpetto February 12, 2025 22:19
@mmiermans mmiermans force-pushed the hnt-405-remove-blocked-topics-from-popular-today branch from 296289d to 3493e69 Compare February 12, 2025 22:24
Copy link
Collaborator

@jpetto jpetto left a comment

Choose a reason for hiding this comment

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

i think it's worth it to cover more scenarios in some unit tests.

blocked_section_ids = {rs.sectionId for rs in request.sections if rs.isBlocked}
recommendations = [
r for r in recommendations if r.topic and r.topic.value not in blocked_section_ids
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think it would be nice to abstract this to a helper function with a few unit tests.

  • verify it's only removing recommendations matching a blocked section
  • verify it does nothing if no sections are marked as blocked
  • verify it handles recommendations without topics as expected (is the expectation that a recommendation without a topic be excluded here? also how do recommendations without a topic get in?)

Copy link
Collaborator

Choose a reason for hiding this comment

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

also - do you think it's worth skipping the list comprehension (i think that's what it's called?) on line 329 if blocked_section_ids has a length of 0?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good question. I was curious what the performance impact was, so I did a quick benchmark:

import timeit
setup_code = '''
class DummyTopic:
    def __init__(self, value):
        self.value = value
class DummyRec:
    def __init__(self, topic):
        self.topic = topic
# Create 10,000 dummy recommendations.
# For this benchmark, each recommendation has a DummyTopic.
recommendations = [DummyRec(DummyTopic("dummy")) for _ in range(1000)]
# blocked_section_ids is empty.
blocked_section_ids = set()
'''
stmt = '''
filtered = [r for r in recommendations if not r.topic or r.topic.value not in blocked_section_ids]
'''
# Run the list comprehension 1000 times and measure the total time.
iterations = 1000
total_time = timeit.timeit(stmt=stmt, setup=setup_code, number=iterations)
avg_time_ms = (total_time / iterations) * 1000
print(f"Average time per iteration: {avg_time_ms:.3f} ms")

Average time per iteration: 0.028 ms

Currently we have a few hundred recommendations. At the cost of a few microseconds, I would lean towards letting list comprehension handle the case of an empty list.

if feed:
for recommendation in feed["recommendations"]:
assert recommendation["topic"] not in blocked_topics

Copy link
Collaborator

Choose a reason for hiding this comment

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

just to say - if the new logic in the above file is fully tested in a unit test, the only line of code this function would really be testing (that isn't already tested) is line 327 in the file above:

if request.sections:

for peace of mind this test isn't bad though.

Copy link
Collaborator

@jpetto jpetto left a comment

Choose a reason for hiding this comment

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

looks much better. great tests and use of a static method!

@@ -311,6 +311,14 @@ async def get_time_sensitive_recommendations(
general_feed = [r for r in recommendations if not r.isTimeSensitive]
return general_feed, need_to_know_feed

@staticmethod
def exclude_recommendations_from_blocked_sections(recommendations, requested_sections):
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice use of a static method!

@mmiermans mmiermans added this pull request to the merge queue Feb 18, 2025
Merged via the queue into main with commit a84eb96 Feb 18, 2025
11 checks passed
@mmiermans mmiermans deleted the hnt-405-remove-blocked-topics-from-popular-today branch February 18, 2025 20:55
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