-
Notifications
You must be signed in to change notification settings - Fork 699
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
TheMediaGrid: Add params.keywords processing #1913
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments
adapters/grid/grid.go
Outdated
var reqExt ReqExt | ||
var reqExtKeywords map[string]interface{} | ||
|
||
if err := json.Unmarshal(request.Ext, &reqExt); err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to have less nested statements can we return if error instead?
if err := json.Unmarshal(request.Ext, &reqExt); err != nil {
return err
}
// ExtImpGrid defines the contract for bidrequest.imp[i].ext.grid | ||
type ExtImpGrid struct { | ||
Uid int `json:"uid"` | ||
Uid int `json:"uid"` | ||
Keywords json.RawMessage `json:"keywords,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please add the keywords
parameter in static/bidder-params/grid.json
with its proper constraints if applicable? (required
or not, minlength
or none)
adapters/grid/grid.go
Outdated
} | ||
} | ||
|
||
func reformatExtKeywords(extKeywords map[string]interface{}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we refactor the reformatExtKeywords(extKeywords map[string]interface{})
function or subdivide it into subfunctions to make it easier to read?
adapters/grid/grid.go
Outdated
for _, item := range pubArr { | ||
switch item.(type) { | ||
// default: | ||
// formatedPubArr = append(formatedPubArr, item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if these couple of lines are of no use, can we remove?
adapters/grid/grid.go
Outdated
|
||
func reformatExtKeywords(extKeywords map[string]interface{}) { | ||
for name, pubData := range extKeywords { | ||
switch pubData.(type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the type switch
statements in lines 160 and 167 only seem to have one case
statement, can we use a type assertion instead?
if v, ok = x.(T); ok {
// ...
}
Or even the reflect library:
x := 42
xtype := reflect.TypeOf(x).Kind()
if xtype == reflect.Int {
println("x is int")
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree with the BidMeta changes to PBS-Core to solve the overwriting problem.
adapters/bidder.go
Outdated
type TypedBid struct { | ||
Bid *openrtb2.Bid | ||
BidType openrtb_ext.BidType | ||
BidVideo *openrtb_ext.ExtBidPrebidVideo | ||
DealPriority int | ||
BidMeta *openrtb_ext.ExtBidPrebidMeta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include BidMeta
alphabetically in the comments and TypedBid
object.
exchange/bidder.go
Outdated
@@ -71,6 +72,7 @@ type pbsOrtbBid struct { | |||
dealPriority int | |||
dealTierSatisfied bool | |||
generatedBidID string | |||
bidMeta *openrtb_ext.ExtBidPrebidMeta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include bidMeta alphabetically in the comments and pbsOrtbBid object.
reqJSON, err := json.Marshal(requestCopy) | ||
err := setImpExtKeywords(validImps[0], request) | ||
if err != nil { | ||
errors = append(errors, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the error thrown in setImpExtKeywords
not worth returning nil
? Among the potential errors that setImpExtKeywords
may throw are Unmarshal
and Marshal
errors. In those cases do we still not want to do:
return nil, errors
?
adapters/grid/grid.go
Outdated
var extKWSite map[string]interface{} | ||
var extKWUser map[string]interface{} | ||
|
||
json.Unmarshal(keywords, &extKeywords) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We realize an error scenario here is unlikely but we believe it's better to try to check for it and handle it
adapters/grid/grid.go
Outdated
return err | ||
} | ||
if reqExt.Keywords != nil { | ||
json.Unmarshal(reqExt.Keywords, &reqExtKeywords) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We realize an error scenario here is unlikely but we believe it's better to try to check for it and handle it
static/bidder-params/grid.json
Outdated
} | ||
}, | ||
"required": [] | ||
"required": ["uid"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any statistics on how many requests come in currently without a "uid"
parameter? There was a design choice that any request that does not pass validation on any one of the bidder JSON validation schemas fails entirely, not just for the one bidder. This was done as when a publisher sets up a new configuration with multiple bidders, a bidder parameter failure on one bidder may be masked by all the successful bids from other bidders. We would rather the requests were correct from the start.
This means any current bidder configs that do not include uid
will fail to fetch ads from any bidder. This will break publisher configs across all bidders, not just yours. The preferred way to add a new required field is to initially list it as optional in the schema, and have the adapter return an error if it is missing. An adapter returning an error outside of JSON schema validation will not invalidate the whole request. Then once we all have some confidence that all the publishers have updated their configs, put in a followup PR to change the schema to required.
@guscarreon @SyntaxNode @hhhjort any chance you could take a look at the most recent changes that we've made as per Scott's comments? Any insight into why the auto tests are failing would be very useful as well. |
I'm looking into it. I didn't see this locally either. I suspect it's a case where the segments array order is indeterminate, but will confirm. |
Found it. The issue is caused by the indeterminate ordering of the segments when constructed from an array of strings, referred to as the "compatible alternate segment format" in the code. The ordering relies on the iteration order of keys within a map, which is purposefully inconsistent in Go. I don't believe the ordering matters to your bidding server, but it does matter to the json tests since arrays are always tested as order dependent. I'm not sure how easily or safely we can modify the test layer, but it easy to sort the keys to ensure deterministic order. Change:
To:
This will then consistently fail until the mixed test is updated to the following order:
After which the tests will consistently passes. I don't believe this is a new issue, but was missed earlier just by chance. |
@SyntaxNode @guscarreon @hhhjort @bsardo can anybody please review this PR? it's been a while |
@@ -19,3 +19,12 @@ func ReadEmbeddedSlice(m map[string]interface{}, k string) ([]interface{}, bool) | |||
|
|||
return nil, false | |||
} | |||
|
|||
// ReadEmbeddedString reads element k from the map m as a string | |||
func ReadEmbeddedString(m map[string]interface{}, k string) (string, bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add test coverage for this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bsardo we added the test as requested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 looks good
@@ -0,0 +1,308 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My personal preference here would be to see some of the invalid cases tested in their own small test files as this is pretty hard to digest. At the same time, I recognize this test adds value as written because it exercises just about all of the keyword logic which raises confidence that it works correctly together. I can be swayed either way. @guscarreon @SyntaxNode thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TheMediaGrid : In order to double-check the expected behavior or your keywords algorithm could you please write 3 more tests where there are keywords:
- In the root.Ext only
- In the root.site only
- In the root.user only
I think your code looks pretty solid and with these three extra tests I'd be good to approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks pretty solid. It'd be nice to add 3 more tests in a follow-up PR where there are keywords:
- In the root.Ext only
- In the root.site only
- In the root.user only
Update s2s TheMediaGrid adapter to read imp.ext.bidder.keywords and copy it in ext.keywords