-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Fix for early auction close with video + done cb cleanup #3024
Changes from 1 commit
2d34382
f9f5052
2288d15
d3b4d4c
9f0240d
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 |
---|---|---|
|
@@ -48,7 +48,7 @@ | |
* @property {function(): void} callBids - sends requests to all adapters for bids | ||
*/ | ||
|
||
import { uniques, flatten, timestamp, adUnitsFilter, delayExecution, getBidderRequest } from './utils'; | ||
import { uniques, flatten, timestamp, adUnitsFilter, getBidderRequest } from './utils'; | ||
import { getPriceBucketString } from './cpmBucketManager'; | ||
import { getNativeTargeting } from './native'; | ||
import { getCacheUrl, store } from './videoCache'; | ||
|
@@ -155,29 +155,21 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) | |
} | ||
} | ||
|
||
function done(bidRequestId) { | ||
const innerBidRequestId = bidRequestId; | ||
return delayExecution(function() { | ||
const request = find(_bidderRequests, (bidRequest) => { | ||
return innerBidRequestId === bidRequest.bidderRequestId; | ||
}); | ||
|
||
// this is done for cache-enabled video bids in tryAddVideoBid, after the cache is stored | ||
request.doneCbCallCount += 1; | ||
bidsBackAll(); | ||
}, 1); | ||
function done(bidderCount) { | ||
let doneCalled = 0; | ||
return function() { | ||
doneCalled++; | ||
if (doneCalled === bidderCount) { | ||
closeAuction(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Execute bidBackHandler if all bidders have called done. | ||
*/ | ||
function bidsBackAll() { | ||
if (_bidderRequests.every((bidRequest) => bidRequest.doneCbCallCount >= 1)) { | ||
// when all bidders have called done callback atleast once it means auction is complete | ||
utils.logInfo(`Bids Received for Auction with id: ${_auctionId}`, _bidsReceived); | ||
_auctionStatus = AUCTION_COMPLETED; | ||
executeCallback(false, true); | ||
} | ||
function closeAuction() { | ||
// when all bidders have called done callback atleast once it means auction is complete | ||
utils.logInfo(`Bids Received for Auction with id: ${_auctionId}`, _bidsReceived); | ||
_auctionStatus = AUCTION_COMPLETED; | ||
executeCallback(false, true); | ||
} | ||
|
||
function callBids() { | ||
|
@@ -206,7 +198,11 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) | |
}; | ||
events.emit(CONSTANTS.EVENTS.AUCTION_INIT, auctionInit); | ||
|
||
adaptermanager.callBids(_adUnits, bidRequests, addBidResponse.bind(this), done.bind(this), { | ||
let callbacks = newCallbacks(done(bidRequests.length), this); | ||
let boundObj = { | ||
localAddBidResponse: callbacks.addBidResponse | ||
} | ||
adaptermanager.callBids(_adUnits, bidRequests, addBidResponse.bind(boundObj), callbacks.adapterDone, { | ||
request(source, origin) { | ||
increment(outstandingRequests, origin); | ||
increment(requests, source); | ||
|
@@ -288,7 +284,6 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) | |
addBidReceived, | ||
executeCallback, | ||
callBids, | ||
bidsBackAll, | ||
addWinningBid, | ||
getWinningBids: () => _winningBids, | ||
getTimeout: () => _timeout, | ||
|
@@ -301,6 +296,51 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) | |
} | ||
} | ||
|
||
export const addBidResponse = createHook('asyncSeries', function(adUnitCode, bid) { | ||
this.localAddBidResponse(adUnitCode, bid); | ||
}, 'addBidResponse'); | ||
|
||
function newCallbacks(done, auctionInstance) { | ||
let outstandingBidsAdded = 0; | ||
let doneCalled = false; | ||
|
||
function afterBidAdded() { | ||
outstandingBidsAdded--; | ||
if (doneCalled && outstandingBidsAdded === 0) { | ||
done() | ||
} | ||
} | ||
|
||
function addBidResponse(adUnitCode, bid) { | ||
outstandingBidsAdded++; | ||
let bidRequests = auctionInstance.getBidRequests(); | ||
let auctionId = auctionInstance.getAuctionId(); | ||
|
||
let bidRequest = getBidderRequest(bidRequests, bid.bidderCode, adUnitCode); | ||
let bidResponse = getPreparedBidForAuction({adUnitCode, bid, bidRequest, auctionId}); | ||
|
||
if (bidResponse.mediaType === 'video') { | ||
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. Should add logic (here?) to clarify only for |
||
tryAddVideoBid(auctionInstance, bidResponse, bidRequest, afterBidAdded); | ||
} else { | ||
addBidToAuction(auctionInstance, bidResponse); | ||
afterBidAdded(); | ||
} | ||
} | ||
|
||
function adapterDone() { | ||
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. what do we need adapterDone for? |
||
// events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest); | ||
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. Can remove commented code (if we truly do not need to emit this event here). |
||
doneCalled = true; | ||
if ((outstandingBidsAdded === 0)) { | ||
done(); | ||
} | ||
} | ||
|
||
return { | ||
addBidResponse, | ||
adapterDone | ||
} | ||
} | ||
|
||
function doCallbacksIfTimedout(auctionInstance, bidResponse) { | ||
if (bidResponse.timeToRespond > auctionInstance.getTimeout() + config.getConfig('timeoutBuffer')) { | ||
auctionInstance.executeCallback(true); | ||
|
@@ -316,7 +356,7 @@ function addBidToAuction(auctionInstance, bidResponse) { | |
} | ||
|
||
// Video bids may fail if the cache is down, or there's trouble on the network. | ||
function tryAddVideoBid(auctionInstance, bidResponse, bidRequest) { | ||
function tryAddVideoBid(auctionInstance, bidResponse, bidRequest, afterBidAdded) { | ||
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. Could remove |
||
let addBid = true; | ||
if (config.getConfig('cache.url')) { | ||
if (!bidResponse.videoCacheKey) { | ||
|
@@ -331,10 +371,8 @@ function tryAddVideoBid(auctionInstance, bidResponse, bidRequest) { | |
if (!bidResponse.vastUrl) { | ||
bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey); | ||
} | ||
// only set this prop after the bid has been cached to avoid early ending auction early in bidsBackAll | ||
bidRequest.doneCbCallCount += 1; | ||
addBidToAuction(auctionInstance, bidResponse); | ||
auctionInstance.bidsBackAll(); | ||
afterBidAdded(); | ||
} | ||
}); | ||
} else if (!bidResponse.vastUrl) { | ||
|
@@ -344,24 +382,10 @@ function tryAddVideoBid(auctionInstance, bidResponse, bidRequest) { | |
} | ||
if (addBid) { | ||
addBidToAuction(auctionInstance, bidResponse); | ||
afterBidAdded(); | ||
} | ||
} | ||
|
||
export const addBidResponse = createHook('asyncSeries', function(adUnitCode, bid) { | ||
let auctionInstance = this; | ||
let bidRequests = auctionInstance.getBidRequests(); | ||
let auctionId = auctionInstance.getAuctionId(); | ||
|
||
let bidRequest = getBidderRequest(bidRequests, bid.bidderCode, adUnitCode); | ||
let bidResponse = getPreparedBidForAuction({adUnitCode, bid, bidRequest, auctionId}); | ||
|
||
if (bidResponse.mediaType === 'video') { | ||
tryAddVideoBid(auctionInstance, bidResponse, bidRequest); | ||
} else { | ||
addBidToAuction(auctionInstance, bidResponse); | ||
} | ||
}, 'addBidResponse'); | ||
|
||
// Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. | ||
// This should be called before addBidToAuction(). | ||
function getPreparedBidForAuction({adUnitCode, bid, bidRequest, auctionId}) { | ||
|
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.
are we concerned that some bidders will call multiple
done
callbacks causing the auction to close early?