Skip to main content

Overview

The Candidate Pipeline is a composable, trait-based framework for building recommendation systems in Rust. It provides a structured approach to fetching, enriching, filtering, scoring, and selecting candidates through a series of well-defined stages.

Core Trait

The CandidatePipeline trait is the main abstraction that defines the entire pipeline execution flow:
candidate-pipeline/candidate_pipeline.rs

Pipeline Stages

The pipeline executes in the following order:
1

Query Hydration

All query hydrators run in parallel to enrich the query with additional data (user features, experiment flags, etc.)
2

Candidate Fetching

All sources run in parallel to retrieve candidate posts from different systems (Thunder, Phoenix, etc.)
3

Candidate Hydration

All hydrators run in parallel to enrich candidates with additional features (author info, video duration, etc.)
4

Filtering

Filters run sequentially to remove unwanted candidates (age, blocked authors, etc.)
5

Scoring

Scorers run sequentially to compute prediction scores and ranking signals
6

Selection

The selector sorts and truncates candidates based on scores
7

Post-Selection Hydration

Additional hydrators run in parallel on the selected candidates
8

Post-Selection Filtering

Additional filters run sequentially on the selected candidates
9

Side Effects

Side effects run asynchronously (logging, metrics, etc.) without blocking the response

Pipeline Stages Enum

candidate-pipeline/candidate_pipeline.rs
This enum is used for logging and metrics to identify which stage a component belongs to.

Error Handling

The framework has robust error handling at each stage:
If a query hydrator fails, the error is logged and the pipeline continues with the original query data.
If a source fails, the error is logged and the pipeline continues with candidates from other sources.
If a hydrator fails or returns mismatched length, the error is logged and candidates remain unmodified.
If a filter fails, the error is logged and the original candidate list is restored (no candidates are filtered).
If a scorer fails or returns mismatched length, the error is logged and candidates remain unscored.

Execution Flow

The main execution method orchestrates the entire pipeline:
candidate-pipeline/candidate_pipeline.rs

Pipeline Result

The pipeline returns a PipelineResult containing:
candidate-pipeline/candidate_pipeline.rs
Vec<C>
All candidates after hydration, before filtering
Vec<C>
Candidates that were filtered out during the pipeline
Vec<C>
Final ranked candidates returned to the user
Arc<Q>
The hydrated query object

HasRequestId Trait

All query types must implement the HasRequestId trait for logging and tracing:
candidate-pipeline/candidate_pipeline.rs

Parallel vs Sequential Execution

Parallel stages (query hydrators, sources, hydrators) use join_all to run all components concurrently for maximum performance.Sequential stages (filters, scorers) run components one at a time, allowing each component to see the results of the previous one.

Sources

Learn about candidate sources (Thunder, Phoenix)

Hydrators

Enrich candidates and queries with features

Filters

Remove unwanted candidates from the pipeline

Scorers

Compute prediction scores for ranking