Inherit mapping when merging exacts into glob
The pattern-analysis worker created the merged glob blank and re-armed mapping, discarding the org ThirdParty and description already resolved on the exacts it absorbed. That forced a full re-map (LLM/web-search) and opened a window where an in-flight exact could vanish mid-mapping. Seed the glob from the merged exacts when they unanimously agree on a single third party, carrying its description too, while still re-arming mapping so the glob derives its own catalog row. With the third party pre-set, the mapping worker skips the expensive org/disambiguation resolution. Conflicting or unresolved groups stay blank as before. The catalog link is deliberately not inherited: it is keyed on the exact pattern string, not the glob template, so the mapping worker resolves the right row itself. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -161,6 +161,16 @@ func (h *patternAnalysisHandler) Process(ctx context.Context, banner coredata.Co
|
||||
|
||||
source := bestSource(group)
|
||||
|
||||
// Carry over the resolved org ThirdParty (and its
|
||||
// description) from the merged exacts when they agree,
|
||||
// so the glob is seeded rather than re-mapped from
|
||||
// scratch. Mapping is still re-armed below so the glob
|
||||
// derives its own catalog row; the pre-set third party
|
||||
// lets the mapping worker skip the expensive org
|
||||
// resolution. Only the insert path consumes these: an
|
||||
// existing glob is reloaded and keeps its own mapping.
|
||||
inheritedThirdPartyID, inheritedDescription := inheritedMapping(group)
|
||||
|
||||
now := time.Now()
|
||||
globPattern := &coredata.TrackerPattern{
|
||||
ID: gid.New(banner.ID.TenantID(), coredata.TrackerPatternEntityType),
|
||||
@@ -172,7 +182,8 @@ func (h *patternAnalysisHandler) Process(ctx context.Context, banner coredata.Co
|
||||
MatchType: coredata.TrackerPatternMatchTypeGlob,
|
||||
DisplayName: key.template,
|
||||
MaxAgeSeconds: maxAge,
|
||||
Description: "",
|
||||
ThirdPartyID: inheritedThirdPartyID,
|
||||
Description: inheritedDescription,
|
||||
Source: source,
|
||||
MappingRequestedAt: &now,
|
||||
CreatedAt: now,
|
||||
@@ -712,6 +723,47 @@ func bestSource(patterns []*coredata.TrackerPattern) *coredata.CookieSource {
|
||||
return &src
|
||||
}
|
||||
|
||||
// inheritedMapping rolls up the resolved org ThirdParty of a group of
|
||||
// exact patterns being merged into a glob, so the glob can be seeded
|
||||
// instead of re-mapped from scratch. It returns a third party only when
|
||||
// every resolved member agrees on a single id: a conflicting group (or
|
||||
// one with no resolved member) returns nil, leaving the glob blank for a
|
||||
// fresh mapping pass. When a third party is chosen, the description of
|
||||
// the first member carrying that same id with non-empty text is returned
|
||||
// too; the catalog link (common_tracker_pattern_id) is deliberately not
|
||||
// inherited, since it is keyed on the exact pattern string rather than
|
||||
// the glob template and the mapping worker derives the right row itself.
|
||||
func inheritedMapping(patterns []*coredata.TrackerPattern) (*gid.GID, string) {
|
||||
var thirdPartyID *gid.GID
|
||||
|
||||
for _, p := range patterns {
|
||||
if p.ThirdPartyID == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if thirdPartyID == nil {
|
||||
thirdPartyID = p.ThirdPartyID
|
||||
continue
|
||||
}
|
||||
|
||||
if *thirdPartyID != *p.ThirdPartyID {
|
||||
return nil, ""
|
||||
}
|
||||
}
|
||||
|
||||
if thirdPartyID == nil {
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
for _, p := range patterns {
|
||||
if p.ThirdPartyID != nil && *p.ThirdPartyID == *thirdPartyID && p.Description != "" {
|
||||
return thirdPartyID, p.Description
|
||||
}
|
||||
}
|
||||
|
||||
return thirdPartyID, ""
|
||||
}
|
||||
|
||||
func (h *patternAnalysisHandler) adoptUncategorisedPatterns(
|
||||
ctx context.Context,
|
||||
tx pg.Tx,
|
||||
|
||||
Reference in New Issue
Block a user