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

Concurrent auctions for Prebid 1.0 #1421

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
6ee842b
Adding timestamp function to utils
jaiminpanchal27 Jul 17, 2017
e7c0580
Auction manager (WIP)
jaiminpanchal27 Jul 17, 2017
b3b1407
WIP
jaiminpanchal27 Jul 18, 2017
cdf168c
Updated targeting with auction instances and added auction status
jaiminpanchal27 Jul 21, 2017
644517c
Updated appnexus and appnexusAst adapter
jaiminpanchal27 Jul 21, 2017
c3b7efe
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Jul 21, 2017
36288a1
Added done callback
jaiminpanchal27 Jul 21, 2017
3f99402
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Jul 24, 2017
3b4e80b
Removing bidmanager functions
jaiminpanchal27 Jul 25, 2017
094a052
Removing deprecated public api functions
jaiminpanchal27 Jul 25, 2017
3192320
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Jul 25, 2017
616409e
remove bidmanager file
jaiminpanchal27 Jul 25, 2017
51a393a
Revert "remove bidmanager file"
jaiminpanchal27 Jul 25, 2017
73bd242
Updated appnexus and rubicon adapters to call done callback after all…
jaiminpanchal27 Jul 26, 2017
51a3b94
Added todo
jaiminpanchal27 Jul 26, 2017
ef4e490
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 3, 2017
87168aa
Fixing circular dependency
jaiminpanchal27 Aug 8, 2017
6300a8d
filter s2s requests
jaiminpanchal27 Aug 10, 2017
aa6c9f9
Emit auction end
jaiminpanchal27 Aug 10, 2017
c59bf05
remove unused stuff from adapters
jaiminpanchal27 Aug 10, 2017
fb485b7
cleanup and fixes
jaiminpanchal27 Aug 10, 2017
52e8ddc
Unit test fixes
jaiminpanchal27 Aug 10, 2017
4b3b907
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 10, 2017
407562a
added setTimeout for each auction instance
jaiminpanchal27 Aug 10, 2017
54e43e3
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 10, 2017
73d93d4
added constants closer to code
jaiminpanchal27 Aug 10, 2017
d0ba5c7
binded auction object inside done method
jaiminpanchal27 Aug 10, 2017
fe380ee
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 10, 2017
aec756b
Adding auctionmanager_spec tests and fixes
jaiminpanchal27 Aug 14, 2017
ed5a815
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 14, 2017
86e4623
Remove breakpoint
jaiminpanchal27 Aug 14, 2017
0fc5ecb
Moving auction to separate file and unit tests
jaiminpanchal27 Aug 15, 2017
29b1cc6
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 15, 2017
072a791
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 18, 2017
2124d0c
Merged manually
jaiminpanchal27 Aug 18, 2017
97d59e0
Merged config api changes
jaiminpanchal27 Aug 18, 2017
279d3ad
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 18, 2017
d3971e9
Passing adunits, adunitscodes via constructor and fixing unit tests
jaiminpanchal27 Aug 18, 2017
6a21fc0
Update calling done callback
jaiminpanchal27 Aug 18, 2017
84abbdb
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 21, 2017
6fe782e
added ajax with timeout
jaiminpanchal27 Aug 25, 2017
7edce5c
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Aug 25, 2017
e9589b1
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 6, 2017
b101bf6
convert targeting module to factory pattern
jaiminpanchal27 Sep 13, 2017
a0b312f
Auction code refactored and unit tests
jaiminpanchal27 Sep 13, 2017
d43bff1
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 14, 2017
a84f3e8
Updated bidderfactory for 1.0 changes and added unit tests
jaiminpanchal27 Sep 14, 2017
dab3373
Renamed placementCode to adUnitCode
jaiminpanchal27 Sep 14, 2017
b5946fb
Refactor auction and update unit tests
jaiminpanchal27 Sep 15, 2017
2e734ff
JSDoc for auction and auctionManager
jaiminpanchal27 Sep 16, 2017
c4553f8
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 16, 2017
a1ddb66
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 19, 2017
ec9d1bf
Unit test fixes after rebase
jaiminpanchal27 Sep 20, 2017
564e985
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 20, 2017
bf1aaa2
Manual merge new updates to bidmanager and its spec file into auction
jaiminpanchal27 Sep 20, 2017
ad393f5
Update appnexusAst spec file
jaiminpanchal27 Sep 21, 2017
4e5b808
Merge branch 'master' of github.com:prebid/Prebid.js into concurrent-…
jaiminpanchal27 Sep 22, 2017
b118982
Refactor
jaiminpanchal27 Sep 22, 2017
91d1e9e
Prebid 1.0 does not require no_bid to be added
jaiminpanchal27 Sep 22, 2017
d3d5d24
removed side effect by cloning objects
jaiminpanchal27 Sep 25, 2017
72ecab4
bug fix to set status on already used bid
jaiminpanchal27 Sep 25, 2017
909863d
Removing all !1.0 complaiant adapters
jaiminpanchal27 Sep 26, 2017
89c6b02
Adding aliases to appnexusAst adapter
jaiminpanchal27 Sep 26, 2017
05697d0
Removed bidmanager from currency
jaiminpanchal27 Sep 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 64 additions & 57 deletions modules/appnexusAstBidAdapter.js
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';
Expand Down Expand Up @@ -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) {
Copy link
Contributor

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.

bidRequests = {};

const bids = bidRequest.bids || [];
Expand Down Expand Up @@ -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 */
Copy link
Contributor

Choose a reason for hiding this comment

The 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 .eslintrc and leave links in comments so that we know why it's disabled. That way if (for example) we switch to rollup or upgrade babel, we'll know whether we have to rethink it.

If (like me) you're too lazy for that, you could also just fix the code by declaring it like const handleResponse = function handleResponse(response) { ... }. Or just move the declarations out of the if block.

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

NO_BID bids shouldn't exist in Prebid 1.0. If there are no bids, adapters can just call done() without ever calling addBidResponse().

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) {
Expand Down
158 changes: 82 additions & 76 deletions modules/appnexusBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand All @@ -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;

Expand All @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The 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 callBids several times. If you're setting a global callback each time, won't the function from one auction trample the function from another?

Copy link
Contributor

Choose a reason for hiding this comment

The 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) {
Expand Down Expand Up @@ -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,
Expand Down
Loading