-
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
Concurrent auctions for Prebid 1.0 #1421
Changes from 15 commits
6ee842b
e7c0580
b3b1407
cdf168c
644517c
c3b7efe
36288a1
3f99402
3b4e80b
094a052
3192320
616409e
51a393a
73bd242
51a3b94
ef4e490
87168aa
6300a8d
aa6c9f9
c59bf05
fb485b7
52e8ddc
4b3b907
407562a
54e43e3
73d93d4
d0ba5c7
fe380ee
aec756b
ed5a815
86e4623
0fc5ecb
29b1cc6
072a791
2124d0c
97d59e0
279d3ad
d3971e9
6a21fc0
84abbdb
6fe782e
7edce5c
e9589b1
b101bf6
a0b312f
d43bff1
a84f3e8
dab3373
b5946fb
2e734ff
c4553f8
a1ddb66
ec9d1bf
564e985
bf1aaa2
ad393f5
4e5b808
b118982
91d1e9e
d3d5d24
72ecab4
909863d
89c6b02
05697d0
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 |
---|---|---|
@@ -1,7 +1,6 @@ | ||
import Adapter from 'src/adapter'; | ||
import { Renderer } from 'src/Renderer'; | ||
import bidfactory from 'src/bidfactory'; | ||
import bidmanager from 'src/bidmanager'; | ||
import * as utils from 'src/utils'; | ||
import { ajax } from 'src/ajax'; | ||
import { STATUS } from 'src/constants'; | ||
|
@@ -36,7 +35,7 @@ function AppnexusAstAdapter() { | |
let usersync = false; | ||
|
||
/* Prebid executes this function when the page asks to send out bid requests */ | ||
baseAdapter.callBids = function(bidRequest) { | ||
baseAdapter.callBids = function(bidRequest, addBidResponse, done) { | ||
bidRequests = {}; | ||
|
||
const bids = bidRequest.bids || []; | ||
|
@@ -150,72 +149,80 @@ function AppnexusAstAdapter() { | |
contentType: 'text/plain', | ||
withCredentials: true | ||
}); | ||
} | ||
}; | ||
|
||
/* Notify Prebid of bid responses so bids can get in the auction */ | ||
function handleResponse(response) { | ||
let parsed; | ||
|
||
try { | ||
parsed = JSON.parse(response); | ||
} catch (error) { | ||
utils.logError(error); | ||
} | ||
/* Notify Prebid of bid responses so bids can get in the auction */ | ||
// Disabled lint for no-inner declaration error | ||
/*eslint-disable */ | ||
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. How sure are you that this is safe? Linter errors usually exist for good reason, and know better than the average programmer. This one looks like it exists because it's not legal ES5. Does our babel/webpack transform it into code which is ES5 compliant? If you've done the research and are certain it's safe, disable it globally in the If (like me) you're too lazy for that, you could also just fix the code by declaring it like |
||
function handleResponse(response) { | ||
let parsed; | ||
|
||
if (!parsed || parsed.error) { | ||
let errorMessage = `in response for ${baseAdapter.getBidderCode()} adapter`; | ||
if (parsed && parsed.error) { errorMessage += `: ${parsed.error}`; } | ||
utils.logError(errorMessage); | ||
try { | ||
parsed = JSON.parse(response); | ||
} catch (error) { | ||
utils.logError(error); | ||
} | ||
|
||
// signal this response is complete | ||
Object.keys(bidRequests) | ||
.map(bidId => bidRequests[bidId].placementCode) | ||
.forEach(placementCode => { | ||
bidmanager.addBidResponse(placementCode, createBid(STATUS.NO_BID)); | ||
}); | ||
return; | ||
} | ||
if (!parsed || parsed.error) { | ||
let errorMessage = `in response for ${baseAdapter.getBidderCode()} adapter`; | ||
if (parsed && parsed.error) { errorMessage += `: ${parsed.error}`; } | ||
utils.logError(errorMessage); | ||
|
||
// signal this response is complete | ||
Object.keys(bidRequests) | ||
.map(bidId => bidRequests[bidId].placementCode) | ||
.forEach(placementCode => { | ||
addBidResponse(placementCode, createBid(STATUS.NO_BID), auctionId); | ||
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.
There'll be far fewer bugs that way. |
||
done(); | ||
}); | ||
return; | ||
} | ||
|
||
parsed.tags.forEach(tag => { | ||
const ad = getRtbBid(tag); | ||
const cpm = ad && ad.cpm; | ||
const type = ad && ad.ad_type; | ||
parsed.tags.forEach(tag => { | ||
const ad = getRtbBid(tag); | ||
const cpm = ad && ad.cpm; | ||
const type = ad && ad.ad_type; | ||
|
||
let status; | ||
if (cpm !== 0 && (SUPPORTED_AD_TYPES.includes(type))) { | ||
status = STATUS.GOOD; | ||
} else { | ||
status = STATUS.NO_BID; | ||
} | ||
let status; | ||
if (cpm !== 0 && (SUPPORTED_AD_TYPES.includes(type))) { | ||
status = STATUS.GOOD; | ||
} else { | ||
status = STATUS.NO_BID; | ||
} | ||
|
||
if (type && (!SUPPORTED_AD_TYPES.includes(type))) { | ||
utils.logError(`${type} ad type not supported`); | ||
} | ||
if (type && (!SUPPORTED_AD_TYPES.includes(type))) { | ||
utils.logError(`${type} ad type not supported`); | ||
} | ||
|
||
tag.bidId = tag.uuid; // bidfactory looks for bidId on requested bid | ||
const bid = createBid(status, tag); | ||
if (type === 'native') bid.mediaType = 'native'; | ||
if (type === 'video') bid.mediaType = 'video'; | ||
if (ad && ad.renderer_url) bid.mediaType = 'video-outstream'; | ||
tag.bidId = tag.uuid; // bidfactory looks for bidId on requested bid | ||
const bid = createBid(status, tag); | ||
if (type === 'native') bid.mediaType = 'native'; | ||
if (type === 'video') bid.mediaType = 'video'; | ||
if (ad && ad.renderer_url) bid.mediaType = 'video-outstream'; | ||
|
||
if (bid.adId in bidRequests) { | ||
const placement = bidRequests[bid.adId].placementCode; | ||
bidmanager.addBidResponse(placement, bid); | ||
} | ||
}); | ||
if (bid.adId in bidRequests) { | ||
const placement = bidRequests[bid.adId].placementCode; | ||
const auctionId = bidRequests[bid.adId].auctionId; | ||
addBidResponse(placement, bid, auctionId); | ||
} | ||
}); | ||
|
||
if (!usersync) { | ||
const iframe = utils.createInvisibleIframe(); | ||
iframe.src = '//acdn.adnxs.com/ib/static/usersync/v3/async_usersync.html'; | ||
try { | ||
document.body.appendChild(iframe); | ||
} catch (error) { | ||
utils.logError(error); | ||
if (!usersync) { | ||
const iframe = utils.createInvisibleIframe(); | ||
iframe.src = '//acdn.adnxs.com/ib/static/usersync/v3/async_usersync.html'; | ||
try { | ||
document.body.appendChild(iframe); | ||
} catch (error) { | ||
utils.logError(error); | ||
} | ||
usersync = true; | ||
} | ||
done(); | ||
} | ||
usersync = true; | ||
/*eslint-enable */ | ||
} | ||
} | ||
}; | ||
|
||
|
||
|
||
/* Check that a bid has required paramters */ | ||
function valid(bid) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ import adaptermanager from 'src/adaptermanager'; | |
var CONSTANTS = require('src/constants'); | ||
var utils = require('src/utils'); | ||
var adloader = require('src/adloader'); | ||
var bidmanager = require('src/bidmanager'); | ||
var bidfactory = require('src/bidfactory'); | ||
var Adapter = require('src/adapter'); | ||
|
||
|
@@ -13,10 +12,11 @@ AppNexusAdapter = function AppNexusAdapter() { | |
var baseAdapter = Adapter.createNew('appnexus'); | ||
var usersync = false; | ||
|
||
baseAdapter.callBids = function (params) { | ||
baseAdapter.callBids = function (bidderRequest, addBidResponse, done) { | ||
// var bidCode = baseAdapter.getBidderCode(); | ||
|
||
var anArr = params.bids; | ||
var anArr = bidderRequest.bids; | ||
var callbackCounter = 0; | ||
|
||
// var bidsCount = anArr.length; | ||
|
||
|
@@ -31,6 +31,85 @@ AppNexusAdapter = function AppNexusAdapter() { | |
// store a reference to the bidRequest from the callback id | ||
// bidmanager.pbCallbackMap[callbackId] = bidRequest; | ||
} | ||
|
||
// expose the callback to the global object: | ||
$$PREBID_GLOBAL$$.handleAnCB = function (jptResponseObj) { | ||
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. Aren't we banning JSONP in Prebid 1.0? I thought that was the plan... Related: What's the intended behavior here? To my eyes, it looks very suspicious (probably buggy?). With concurrent auctions, prebid-core is going to call 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. Unrelated... but this also looks like it conflicts/tramples the declaration down around line 221. Github won't let me leave a comment there because it's not near code you actually changed. |
||
var bidCode; | ||
callbackCounter++; | ||
|
||
if (jptResponseObj && jptResponseObj.callback_uid) { | ||
var responseCPM; | ||
var id = jptResponseObj.callback_uid; | ||
var placementCode = ''; | ||
var bidObj = bidderRequest.bids.find(bid => bid.bidId === id); // getBidRequest(id); | ||
if (bidObj) { | ||
bidCode = bidObj.bidder; | ||
|
||
placementCode = bidObj.placementCode; | ||
|
||
// set the status | ||
bidObj.status = CONSTANTS.STATUS.GOOD; | ||
} | ||
|
||
// @if NODE_ENV='debug' | ||
utils.logMessage('JSONP callback function called for ad ID: ' + id); | ||
|
||
// @endif | ||
var bid = []; | ||
if (jptResponseObj.result && jptResponseObj.result.cpm && jptResponseObj.result.cpm !== 0) { | ||
responseCPM = parseInt(jptResponseObj.result.cpm, 10); | ||
|
||
// CPM response from /jpt is dollar/cent multiplied by 10000 | ||
// in order to avoid using floats | ||
// switch CPM to "dollar/cent" | ||
responseCPM = responseCPM / 10000; | ||
|
||
// store bid response | ||
// bid status is good (indicating 1) | ||
var adId = jptResponseObj.result.creative_id; | ||
bid = bidfactory.createBid(1, bidObj); | ||
bid.creative_id = adId; | ||
bid.bidderCode = bidCode; | ||
bid.cpm = responseCPM; | ||
bid.adUrl = jptResponseObj.result.ad; | ||
bid.width = jptResponseObj.result.width; | ||
bid.height = jptResponseObj.result.height; | ||
bid.dealId = jptResponseObj.result.deal_id; | ||
|
||
addBidResponse(placementCode, bid, bidderRequest.auctionId); | ||
} else { | ||
// no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response from AppNexus for placement code ' + placementCode); | ||
|
||
// @endif | ||
// indicate that there is no bid for this placement | ||
bid = bidfactory.createBid(2, bidObj); | ||
bid.bidderCode = bidCode; | ||
addBidResponse(placementCode, bid, bidderRequest.auctionId); | ||
} | ||
|
||
if (!usersync) { | ||
var iframe = utils.createInvisibleIframe(); | ||
iframe.src = '//acdn.adnxs.com/ib/static/usersync/v3/async_usersync.html'; | ||
try { | ||
document.body.appendChild(iframe); | ||
} catch (error) { | ||
utils.logError(error); | ||
} | ||
usersync = true; | ||
} | ||
} else { | ||
// no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response for placement %%PLACEMENT%%'); | ||
|
||
// @endif | ||
} | ||
if (callbackCounter === anArr.length) { | ||
done(); | ||
} | ||
}; | ||
}; | ||
|
||
function buildJPTCall(bid, callbackId) { | ||
|
@@ -139,80 +218,7 @@ AppNexusAdapter = function AppNexusAdapter() { | |
return jptCall; | ||
} | ||
|
||
// expose the callback to the global object: | ||
$$PREBID_GLOBAL$$.handleAnCB = function (jptResponseObj) { | ||
var bidCode; | ||
|
||
if (jptResponseObj && jptResponseObj.callback_uid) { | ||
var responseCPM; | ||
var id = jptResponseObj.callback_uid; | ||
var placementCode = ''; | ||
var bidObj = getBidRequest(id); | ||
if (bidObj) { | ||
bidCode = bidObj.bidder; | ||
|
||
placementCode = bidObj.placementCode; | ||
|
||
// set the status | ||
bidObj.status = CONSTANTS.STATUS.GOOD; | ||
} | ||
|
||
// @if NODE_ENV='debug' | ||
utils.logMessage('JSONP callback function called for ad ID: ' + id); | ||
|
||
// @endif | ||
var bid = []; | ||
if (jptResponseObj.result && jptResponseObj.result.cpm && jptResponseObj.result.cpm !== 0) { | ||
responseCPM = parseInt(jptResponseObj.result.cpm, 10); | ||
|
||
// CPM response from /jpt is dollar/cent multiplied by 10000 | ||
// in order to avoid using floats | ||
// switch CPM to "dollar/cent" | ||
responseCPM = responseCPM / 10000; | ||
|
||
// store bid response | ||
// bid status is good (indicating 1) | ||
var adId = jptResponseObj.result.creative_id; | ||
bid = bidfactory.createBid(1, bidObj); | ||
bid.creative_id = adId; | ||
bid.bidderCode = bidCode; | ||
bid.cpm = responseCPM; | ||
bid.adUrl = jptResponseObj.result.ad; | ||
bid.width = jptResponseObj.result.width; | ||
bid.height = jptResponseObj.result.height; | ||
bid.dealId = jptResponseObj.result.deal_id; | ||
|
||
bidmanager.addBidResponse(placementCode, bid); | ||
} else { | ||
// no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response from AppNexus for placement code ' + placementCode); | ||
|
||
// @endif | ||
// indicate that there is no bid for this placement | ||
bid = bidfactory.createBid(2, bidObj); | ||
bid.bidderCode = bidCode; | ||
bidmanager.addBidResponse(placementCode, bid); | ||
} | ||
|
||
if (!usersync) { | ||
var iframe = utils.createInvisibleIframe(); | ||
iframe.src = '//acdn.adnxs.com/ib/static/usersync/v3/async_usersync.html'; | ||
try { | ||
document.body.appendChild(iframe); | ||
} catch (error) { | ||
utils.logError(error); | ||
} | ||
usersync = true; | ||
} | ||
} else { | ||
// no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response for placement %%PLACEMENT%%'); | ||
|
||
// @endif | ||
} | ||
}; | ||
|
||
return { | ||
callBids: baseAdapter.callBids, | ||
|
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.
As long as you're rewriting these... you might want to check out the format proposed by @snapwich
Other adapter maintainers are going to look to these for inspiration... so setting a good pattern will pay dividends in maintenance.