-
Notifications
You must be signed in to change notification settings - Fork 750
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
Introduce SeatNonBid in hookoutcome #3416
base: master
Are you sure you want to change the base?
Changes from 4 commits
8678237
acef141
c6525bc
47b5c6f
ffe2748
72e625e
423a30f
9450e40
6cd54de
2dac953
dbaff7e
35f2d02
e62b33a
33bf0e5
fd14752
dfc26e7
f952f90
956c51e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,6 +117,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |
// We can respect timeouts more accurately if we note the *real* start time, and use it | ||
// to compute the auction timeout. | ||
start := time.Now() | ||
seatNonBid := &openrtb_ext.NonBidsWrapper{} | ||
|
||
hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAmp, deps.metricsEngine) | ||
|
||
|
@@ -138,6 +139,12 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |
activityControl := privacy.ActivityControl{} | ||
|
||
defer func() { | ||
// if AmpObject.AuctionResponse is nil then collect nonbids from all stage outcomes and set it in the AmpObject.SeatNonBid | ||
// Nil AmpObject.AuctionResponse indicates the occurrence of a fatal error. | ||
if ao.AuctionResponse == nil { | ||
seatNonBid.Append(getNonBidsFromStageOutcomes(hookExecutor.GetOutcomes())) | ||
ao.SeatNonBid = seatNonBid.Get() | ||
} | ||
deps.metricsEngine.RecordRequest(labels) | ||
deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) | ||
deps.analytics.LogAmpObject(&ao, activityControl) | ||
|
@@ -164,7 +171,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |
// Process reject after parsing amp request, so we can use reqWrapper. | ||
// There is no body for AMP requests, so we pass a nil body and ignore the return value. | ||
if rejectErr != nil { | ||
labels, ao = rejectAmpRequest(*rejectErr, w, hookExecutor, reqWrapper, nil, labels, ao, nil) | ||
labels, ao = rejectAmpRequest(*rejectErr, w, hookExecutor, reqWrapper, nil, labels, ao, nil, seatNonBid) | ||
return | ||
} | ||
|
||
|
@@ -267,8 +274,9 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |
var response *openrtb2.BidResponse | ||
if auctionResponse != nil { | ||
response = auctionResponse.BidResponse | ||
seatNonBid.Append(auctionResponse.SeatNonBid) | ||
|
||
} | ||
ao.SeatNonBid = auctionResponse.GetSeatNonBid() | ||
ao.AuctionResponse = response | ||
rejectErr, isRejectErr := hookexecution.CastRejectErr(err) | ||
if err != nil && !isRejectErr { | ||
|
@@ -288,15 +296,21 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h | |
glog.Errorf("/openrtb2/amp Critical error: %v", err) | ||
ao.Status = http.StatusInternalServerError | ||
ao.Errors = append(ao.Errors, err) | ||
if ao.AuctionResponse != nil { | ||
// this check ensures that we collect nonBids from stageOutcomes only once. | ||
// there could be a case where ao.AuctionResponse nil and reqWrapper.RebuildRequest returns error | ||
seatNonBid.Append(getNonBidsFromStageOutcomes(hookExecutor.GetOutcomes())) | ||
ao.SeatNonBid = seatNonBid.Get() | ||
} | ||
Comment on lines
+318
to
+323
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this needed here? It duplicates logic from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in defer, we are collecting non-bids only when ao.AuctionResponse is nil. |
||
return | ||
} | ||
|
||
if isRejectErr { | ||
labels, ao = rejectAmpRequest(*rejectErr, w, hookExecutor, reqWrapper, account, labels, ao, errL) | ||
labels, ao = rejectAmpRequest(*rejectErr, w, hookExecutor, reqWrapper, account, labels, ao, errL, seatNonBid) | ||
return | ||
} | ||
|
||
labels, ao = sendAmpResponse(w, hookExecutor, auctionResponse, reqWrapper, account, labels, ao, errL) | ||
labels, ao = sendAmpResponse(w, hookExecutor, auctionResponse, reqWrapper, account, labels, ao, errL, seatNonBid) | ||
} | ||
|
||
func rejectAmpRequest( | ||
|
@@ -308,12 +322,13 @@ func rejectAmpRequest( | |
labels metrics.Labels, | ||
ao analytics.AmpObject, | ||
errs []error, | ||
seatNonBid *openrtb_ext.NonBidsWrapper, | ||
) (metrics.Labels, analytics.AmpObject) { | ||
response := &openrtb2.BidResponse{NBR: openrtb3.NoBidReason(rejectErr.NBR).Ptr()} | ||
ao.AuctionResponse = response | ||
ao.Errors = append(ao.Errors, rejectErr) | ||
|
||
return sendAmpResponse(w, hookExecutor, &exchange.AuctionResponse{BidResponse: response}, reqWrapper, account, labels, ao, errs) | ||
return sendAmpResponse(w, hookExecutor, &exchange.AuctionResponse{BidResponse: response}, reqWrapper, account, labels, ao, errs, seatNonBid) | ||
} | ||
|
||
func sendAmpResponse( | ||
|
@@ -325,6 +340,7 @@ func sendAmpResponse( | |
labels metrics.Labels, | ||
ao analytics.AmpObject, | ||
errs []error, | ||
seatNonBid *openrtb_ext.NonBidsWrapper, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this passed as a pointer / by reference? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to pass it as pointer. corrected it. |
||
) (metrics.Labels, analytics.AmpObject) { | ||
var response *openrtb2.BidResponse | ||
if auctionResponse != nil { | ||
|
@@ -352,6 +368,8 @@ func sendAmpResponse( | |
glog.Errorf("/openrtb2/amp Critical error unpacking targets: %v", err) | ||
ao.Errors = append(ao.Errors, fmt.Errorf("Critical error while unpacking AMP targets: %v", err)) | ||
ao.Status = http.StatusInternalServerError | ||
seatNonBid.Append(getNonBidsFromStageOutcomes(hookExecutor.GetOutcomes())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Related to my above comment, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, made correction. Now passing the seatNonBid as a copy. |
||
ao.SeatNonBid = seatNonBid.Get() | ||
return labels, ao | ||
} | ||
for key, value := range bidExt.Prebid.Targeting { | ||
|
@@ -380,7 +398,7 @@ func sendAmpResponse( | |
} | ||
// Now JSONify the targets for the AMP response. | ||
ampResponse := AmpResponse{Targeting: targets} | ||
ao, ampResponse.ORTB2.Ext = getExtBidResponse(hookExecutor, auctionResponse, reqWrapper, account, ao, errs) | ||
ao, ampResponse.ORTB2.Ext = getExtBidResponse(hookExecutor, auctionResponse, reqWrapper, account, ao, errs, seatNonBid) | ||
|
||
ao.AmpTargetingValues = targets | ||
|
||
|
@@ -406,6 +424,7 @@ func getExtBidResponse( | |
account *config.Account, | ||
ao analytics.AmpObject, | ||
errs []error, | ||
seatNonBid *openrtb_ext.NonBidsWrapper, | ||
) (analytics.AmpObject, openrtb_ext.ExtBidResponse) { | ||
var response *openrtb2.BidResponse | ||
if auctionResponse != nil { | ||
|
@@ -435,6 +454,7 @@ func getExtBidResponse( | |
Warnings: warnings, | ||
} | ||
|
||
stageOutcomes := hookExecutor.GetOutcomes() | ||
// add debug information if requested | ||
if reqWrapper != nil { | ||
if reqWrapper.Test == 1 && eRErr == nil { | ||
|
@@ -446,7 +466,6 @@ func getExtBidResponse( | |
} | ||
} | ||
|
||
stageOutcomes := hookExecutor.GetOutcomes() | ||
ao.HookExecutionOutcome = stageOutcomes | ||
modules, warns, err := hookexecution.GetModulesJSON(stageOutcomes, reqWrapper.BidRequest, account) | ||
if err != nil { | ||
|
@@ -462,8 +481,12 @@ func getExtBidResponse( | |
} | ||
} | ||
|
||
setSeatNonBid(&extBidResponse, reqWrapper, auctionResponse) | ||
|
||
// collect seatNonBid from all stage-outcomes and set in the response.ext.prebid | ||
seatNonBid.Append(getNonBidsFromStageOutcomes(stageOutcomes)) | ||
ao.SeatNonBid = seatNonBid.Get() | ||
if returnAllBidStatus(reqWrapper) { | ||
setSeatNonBid(&extBidResponse, ao.SeatNonBid) | ||
} | ||
return ao, extBidResponse | ||
} | ||
|
||
|
@@ -843,23 +866,3 @@ func setTrace(req *openrtb2.BidRequest, value string) error { | |
|
||
return nil | ||
} | ||
|
||
// setSeatNonBid populates bidresponse.ext.prebid.seatnonbid if bidrequest.ext.prebid.returnallbidstatus is true | ||
func setSeatNonBid(finalExtBidResponse *openrtb_ext.ExtBidResponse, request *openrtb_ext.RequestWrapper, auctionResponse *exchange.AuctionResponse) bool { | ||
if finalExtBidResponse == nil || auctionResponse == nil || request == nil { | ||
return false | ||
} | ||
reqExt, err := request.GetRequestExt() | ||
if err != nil { | ||
return false | ||
} | ||
prebid := reqExt.GetPrebid() | ||
if prebid == nil || !prebid.ReturnAllBidStatus { | ||
return false | ||
} | ||
if finalExtBidResponse.Prebid == nil { | ||
finalExtBidResponse.Prebid = &openrtb_ext.ExtResponsePrebid{} | ||
} | ||
finalExtBidResponse.Prebid.SeatNonBid = auctionResponse.GetSeatNonBid() | ||
return true | ||
} |
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 there a more direct way for checking the occurrence of a fatal error instead of needing to explain the significance of an empty response in a comment? Hopefully one we can reuse in other parts of the code instead of copying/pasting this comment.
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.
One direct way would be to call below 2 lines after every
return
statement.seatNonBid.Append(getNonBidsFromStageOutcomes(hookExecutor.GetOutcomes()))
ao.SeatNonBid = seatNonBid.Get()
But currently there are around 6/7
return
statement inAuction()
&AmpAuction()
function. To avoid the repetitive code, added this block in defer statement.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.
I think defer block is a good place for this.
Can we rely on the errors in
ao
? Looks like fatal errors should be added inao
in case of every error in the endpoint, like:ao.Errors = append(ao.Errors, rejectErr)
Same for equivalent logic in "auction.go"
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.
You could perhaps have a
foundErrors
boolean flag that starts false, and then is set to true whenever errors are detected. Then use this flag in the defer rather than checking for nil, resulting in a more straightforward way to satisfy the conditional, and futureproofing against any possible change where either an error happens afterao.AuctionResponse
is set or it stays nil despite no error.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.
Used
foundError
instead ofao.Response
nil check.