Skip to content

Deduplicate in_network_ids before VF lookup - #88

Open
joshs1017dev wants to merge 1 commit into
xai-org:mainfrom
joshs1017dev:dedup-in-network-vf-ids
Open

Deduplicate in_network_ids before VF lookup#88
joshs1017dev wants to merge 1 commit into
xai-org:mainfrom
joshs1017dev:dedup-in-network-vf-ids

Conversation

@joshs1017dev

Copy link
Copy Markdown

Summary

VFCandidateHydrator::hydrate builds two ID lists, but only one of them is deduplicated:

oon_ids.sort_unstable();
oon_ids.dedup();

in_network_ids is never deduped, so duplicate tweet IDs are sent to the VF client on
every home-timeline request.

Why duplicates occur in practice

retweeted_tweet_id is pushed to in_network_ids unconditionally for every candidate
that has one — independent of the candidate's own in_network flag:

if let Some(retweeted_id) = candidate.retweeted_tweet_id {
    in_network_ids.push(retweeted_id);
}

So the list contains a duplicate whenever:

  1. Several candidates retweet the same post. The same retweeted_tweet_id is pushed
    once per retweet. This is most likely exactly when a post is going viral, i.e. when
    candidate sets are largest.
  2. An in-network candidate is also another candidate's retweet target. The ID is
    pushed once as candidate.tweet_id and again as retweeted_tweet_id.

Why it costs something

Neither VfClient implementation deduplicates its input:

  • StratoVfClient builds one Strato call per element of tweet_ids and dispatches
    them together, so each duplicate is a redundant subcall in the batch.
  • XaiVfClient splits the input with tweet_ids.chunks(XAI_VF_MAX_BATCH_SIZE), so
    duplicates consume batch slots and can push the request into an additional chunk — an
    extra round trip that carries no new information.

This is not a correctness issue: results are collected into a HashMap keyed by tweet ID,
so duplicates collapse on the way back. It is purely wasted work on the For You serving
path, and it scales with how popular the retweeted posts in the candidate set are.

Precedent in the codebase

Both nearby cases already dedupe before dispatch:

  • oon_ids, four lines below, in this same function.
  • post_ids in vf_following_candidate_hydrator.rs, which dedupes its single list.

This change simply makes in_network_ids consistent with both.

The change

in_network_ids.sort_unstable();
in_network_ids.dedup();

Two lines, mirroring the adjacent oon_ids handling.

Testing

I was not able to compile or run tests against this: the published repository has no
workspace Cargo.toml for home-mixer, so the crate isn't buildable standalone from the
open-source export. The change is deliberately limited to the same two-call pattern used
on the adjacent list to keep it verifiable by inspection.

Happy to add a test with a recording VfClient mock asserting no duplicate IDs reach
get_result if that's useful — ScoredPostsQuery derives Default, so the fixture is
straightforward, but I'd rather not add a test I can't run.

in_network_ids is passed to the VF client without deduplication, while
oon_ids is deduped four lines below. retweeted_tweet_id is pushed for
every candidate that has one, so the same ID repeats once per retweet of
a given post — most often when that post is going viral.

Neither VfClient implementation dedupes its input: StratoVfClient builds
one call per element, and XaiVfClient chunks by XAI_VF_MAX_BATCH_SIZE, so
duplicates consume batch slots and can force an extra round trip.

Not a correctness issue — results collapse into a HashMap keyed by tweet
ID — but redundant work on the For You serving path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant