DedupMiddleware¶
Use this when: duplicate records should be stopped before they reach expensive or irreversible downstream work.
DedupMiddleware combines a key extractor with a store and, optionally, a
matching strategy.
What it does¶
- computes a dedup key from each record
- checks whether that key has already been seen
- drops duplicates
- stores new keys when the record is accepted
When it is a good fit¶
- records have a stable identity such as
id,slug, or external key - duplicate delivery is expected from the upstream source
- downstream writes should be reduced before they reach a sink
Exact and fuzzy modes¶
- exact mode is the default and is the normal production choice
- fuzzy mode compares the new key against previously seen keys through a
strategy such as
FuzzyMatchStrategy
Fuzzy mode is more expensive and keeps an in-memory list of seen keys. It is best for modest working sets, not large-scale semantic matching.
Store failure behavior¶
store_failure_policy controls what happens if the backing dedup store fails:
fail_closed: raise and let the runtime treat it as a middleware failurefail_open: log the store error and pass the record through
Example: exact dedup¶
from agora.middlewares.dedup import DedupMiddleware
pipeline.pipe(DedupMiddleware(key=lambda record: str(record["id"])))
Example: fuzzy dedup¶
from agora.middlewares.dedup import DedupMiddleware
from agora.middlewares.dedup.stores.memory import InMemoryStore
from agora.middlewares.dedup.strategies.fuzzy import FuzzyMatchStrategy
pipeline.pipe(
DedupMiddleware(
key=lambda record: record["name"].lower(),
store=InMemoryStore(),
strategy=FuzzyMatchStrategy(threshold=0.85),
max_fuzzy_keys=100_000,
)
)
When to choose something else¶
- use sink-side upsert logic when duplicates must still reach the destination
- use plugin-backed stores such as Redis for shared dedup across workers or pods