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

Debug Flag for Cookie Sync #3107

Merged
merged 19 commits into from
Nov 16, 2023
Merged

Conversation

AlexBVolcy
Copy link
Contributor

@AlexBVolcy AlexBVolcy commented Sep 14, 2023

Adds debug flag for cookie sync endpoint as described in this issue #2173

@AlexBVolcy AlexBVolcy marked this pull request as draft September 14, 2023 21:40
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync.go Outdated Show resolved Hide resolved
endpoints/cookie_sync_test.go Show resolved Hide resolved
usersync/chooser.go Show resolved Hide resolved
@AlexBVolcy AlexBVolcy marked this pull request as ready for review September 20, 2023 16:25
Comment on lines 430 to 442
if debug {
biddersSeen := make(map[string]struct{})
var debugMessages []string
for _, bidderEval := range biddersEvaluted {
if bidderEval.Status == usersync.StatusDuplicate && biddersSeen[bidderEval.Bidder] == struct{}{} {
debugMessages = append(debugMessages, getDebugMessage(bidderEval.Status)+" synced as "+bidderEval.SyncerKey)
} else if bidderEval.Status != usersync.StatusDuplicate {
debugMessages = append(debugMessages, getDebugMessage(bidderEval.Status))
}
biddersSeen[bidderEval.Bidder] = struct{}{}
}
response.Debug = debugMessages
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I tested it with activities where only "pubmatic" and "appnexus" are allowed.
Request to cookie_sync:

{
    "bidders": ["appnexus", "pubmatic", "adf", "synacormedia"],
    "debug":true
}

Expected: 2 bidders ("adf", "synacormedia") are rejected by privacy and 2 bidders are allowed.
Here is debug part of response:

"debug": [
        "",
        "Rejected by privacy",
        "Rejected by privacy",
        ""
    ]

Can you please add bidder name to message, f.i "Rejected by privacy: synacormedia" and remove empty strings from debug messages.
In activity requirements it states that message should be "Bidder sync blocked for privacy reasons". Not sure what our message should be, I feel like having bidder name in it is reasonable.

Also, about debug flag in request. Here it is a field in json body: "debug": true
Is it confirmed it should be like this?
I'm asking because we handle debug flag differently in different endpoints. F.i. in /action it is "test": 1

Copy link
Contributor

Choose a reason for hiding this comment

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

@AlexBVolcy Please match the response format established with PBS-Java.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree here. I also want to point out that it seems that some of our syncer error messages are a bit different from PBS-Java. I think that's ok. @SyntaxNode, @VeronikaSolovei9 thoughts? What's most important is that the request and response formats are the same.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should match the debug messages too. Unless they reference the "cookie family", which is called the "syncer key" in Go.

Copy link
Contributor Author

@AlexBVolcy AlexBVolcy Sep 28, 2023

Choose a reason for hiding this comment

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

@SyntaxNode @VeronikaSolovei9 @bsardo So here are the debug messages that PBS-Java uses

builder = switch (reason) {
    case INVALID_BIDDER -> builder.conditionalError(requested, "Unsupported bidder");
    case DISABLED_BIDDER -> builder.conditionalError(requested, "Disabled bidder");
    case REJECTED_BY_TCF -> builder.conditionalError(requested || coopSync, "Rejected by TCF");
    case REJECTED_BY_CCPA -> builder.conditionalError(requested || coopSync, "Rejected by CCPA");
    case DISALLOWED_ACTIVITY -> builder.conditionalError(requested || coopSync, "Disallowed activity");
    case UNCONFIGURED_USERSYNC -> builder.conditionalError(requested, "No sync config");
    case DISABLED_USERSYNC -> builder.conditionalError(requested || coopSync, "Sync disabled by config");
    case REJECTED_BY_FILTER -> builder.conditionalError(requested || coopSync, "Rejected by request filter");
    case ALREADY_IN_SYNC -> builder.conditionalError(requested, "Already in sync");
};

I tried to match debug messages the best I could, but there are some statues in my PR that don't overlap with the PBS-Java statuses (i.e. StatusTypeNotSupported), so in those cases I came up with my own debug message. Is this alright?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And yes @VeronikaSolovei9, the debug flag in the request should be like this debug: true

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for addressing comments, just checked it locally and it works as expected.
Question: for bidders restricted by activity here is an expected message:
case DISALLOWED_ACTIVITY -> builder.conditionalError(requested || coopSync, "Disallowed activity");
In this PR we have "Rejected by privacy: synacormedia" (I know I asked about the bidder name).
Should it be? Disallowed activity?

usersync/chooser.go Show resolved Hide resolved
Comment on lines 430 to 442
if debug {
biddersSeen := make(map[string]struct{})
var debugMessages []string
for _, bidderEval := range biddersEvaluted {
if bidderEval.Status == usersync.StatusDuplicate && biddersSeen[bidderEval.Bidder] == struct{}{} {
debugMessages = append(debugMessages, getDebugMessage(bidderEval.Status)+" synced as "+bidderEval.SyncerKey)
} else if bidderEval.Status != usersync.StatusDuplicate {
debugMessages = append(debugMessages, getDebugMessage(bidderEval.Status))
}
biddersSeen[bidderEval.Bidder] = struct{}{}
}
response.Debug = debugMessages
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree here. I also want to point out that it seems that some of our syncer error messages are a bit different from PBS-Java. I think that's ok. @SyntaxNode, @VeronikaSolovei9 thoughts? What's most important is that the request and response formats are the same.

Comment on lines 430 to 434
if debug {
biddersSeen := make(map[string]struct{})
var debugInfo []cookieSyncResponseDebug
for _, bidderEval := range biddersEvaluated {
var debug cookieSyncResponseDebug
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: if debug { and var debug cookieSyncResponseDebug create an ambiguity in variables names.
Can you rename var debug cookieSyncResponseDebug to var debugResponse cookieSyncResponseDebug, or something else that makes sense to you?

Copy link
Contributor

@VeronikaSolovei9 VeronikaSolovei9 left a comment

Choose a reason for hiding this comment

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

Local testing looks good. Added minor comment about naming

Copy link
Contributor

@VeronikaSolovei9 VeronikaSolovei9 left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines -390 to +392
case usersync.StatusBlockedByGDPR:
c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncPrivacyBlocked)
case usersync.StatusBlockedByCCPA:
case usersync.StatusBlockedByPrivacy:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm curious what's driving the change from regulation-specific statuses to a more generic privacy status. Was there a discussion about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Scott and I did have a conversation a while ago and this name change was brought up I think in conjunction with removing CCPA from the evaluate() function. @SyntaxNode I think could touch on this more.

Comment on lines +485 to +486
case usersync.StatusDuplicate:
return "Duplicate bidder"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this equivalent to PBS-Java's "synced as FAMILY" status or is there a difference here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes this is the equivalent, and it'll have appended to it: synced as name_of_bidder_syncer

}

syncersSeen := make(map[string]struct{})
biddersSeen := make(map[string]struct{})
limitDisabled := request.Limit <= 0

biddersEvaluated := make([]BidderEvaluation, 0)
syncersChosen := make([]SyncerChoice, 0)

bidders := c.bidderChooser.choose(request.Bidders, c.biddersAvailable, request.Cooperative)
for i := 0; i < len(bidders) && (limitDisabled || len(syncersChosen) < request.Limit); i++ {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure if this is necessary, but I see that PBS-Java provides debug information indicating when a bidder is ignored because the limit has been reached. Similarly they are indicating if a bidder is known but disabled. We should discuss whether we want to add this logic, perhaps in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh interesting, yeah let's talk about this at the next team time.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Discussed offline. PBS-Go behavior is different from PBS-Java. We stop processing when we reach the limit so there's no need to report on this.

endpoints/cookie_sync.go Outdated Show resolved Hide resolved
},
{
description: "Case Insensitivity Check For Blocked By CCPA",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we should keep this case insensitivitiy test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed it primarily because we removed the CCPA check from the evaluate() logic, thus making this test case unnecessary.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oops I didn't realize there was a GDPR case insensitivity test case above this one. It makes sense to delete this.

@bsardo bsardo merged commit 905436f into prebid:master Nov 16, 2023
3 checks passed
svamiftah pushed a commit to sovrn/prebid-server that referenced this pull request Nov 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants