Skip to content

Commit

Permalink
Make size mapping mediaType aware (prebid#3134)
Browse files Browse the repository at this point in the history
* make sizeMapping mediaTypes aware

* no sizeMapping if the only mediaType is not banner

* better logging for size mapping and no auction when no bids

* fix size mapping tests to ignore filter results (which are only for logging)
  • Loading branch information
snapwich authored and Pedro López Jiménez committed Mar 18, 2019
1 parent 05645d8 commit a680824
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 141 deletions.
55 changes: 34 additions & 21 deletions src/adaptermanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,22 @@ function getLabels(bidOrAdUnit, activeLabels) {

function getBids({bidderCode, auctionId, bidderRequestId, adUnits, labels}) {
return adUnits.reduce((result, adUnit) => {
let bannerSizes = utils.deepAccess(adUnit, 'mediaTypes.banner.sizes');

let {active, sizes: filteredAdUnitSizes} = resolveStatus(
let {
active,
mediaTypes: filteredMediaTypes,
filterResults
} = resolveStatus(
getLabels(adUnit, labels),
bannerSizes || adUnit.sizes
adUnit.mediaTypes,
adUnit.sizes
);

if (!active) {
utils.logInfo(`Size mapping disabled adUnit "${adUnit.code}"`);
} else if (filterResults) {
utils.logInfo(`Size mapping filtered adUnit "${adUnit.code}" banner sizes from `, filterResults.before, 'to ', filterResults.after);
}

if (active) {
result.push(adUnit.bids.filter(bid => bid.bidder === bidderCode)
.reduce((bids, bid) => {
Expand All @@ -72,29 +81,33 @@ function getBids({bidderCode, auctionId, bidderRequestId, adUnits, labels}) {
'renderer'
]));

let {active, sizes} = resolveStatus(getLabels(bid, labels), filteredAdUnitSizes);

if (adUnit.mediaTypes) {
if (utils.isValidMediaTypes(adUnit.mediaTypes)) {
if (bannerSizes) {
adUnit.mediaTypes.banner.sizes = sizes;
}

bid = Object.assign({}, bid, {
mediaTypes: adUnit.mediaTypes
});
} else {
utils.logError(
`mediaTypes is not correctly configured for adunit ${adUnit.code}`
);
}
let {
active,
mediaTypes,
filterResults
} = resolveStatus(getLabels(bid, labels), filteredMediaTypes);

if (!active) {
utils.logInfo(`Size mapping deactivated adUnit "${adUnit.code}" bidder "${bid.bidder}"`);
} else if (filterResults) {
utils.logInfo(`Size mapping filtered adUnit "${adUnit.code}" bidder "${bid.bidder}" banner sizes from `, filterResults.before, 'to ', filterResults.after);
}

if (utils.isValidMediaTypes(mediaTypes)) {
bid = Object.assign({}, bid, {
mediaTypes
});
} else {
utils.logError(
`mediaTypes is not correctly configured for adunit ${adUnit.code}`
);
}

if (active) {
bids.push(Object.assign({}, bid, {
adUnitCode: adUnit.code,
transactionId: adUnit.transactionId,
sizes: sizes,
sizes: utils.deepAccess(mediaTypes, 'banner.sizes') || [],
bidId: bid.bid_id || utils.getUniqueIdentifierStr(),
bidderRequestId,
auctionId,
Expand Down
94 changes: 49 additions & 45 deletions src/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,54 +175,58 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels})

let requests = {};

let call = {
bidRequests,
run: () => {
startAuctionTimer();

_auctionStatus = AUCTION_IN_PROGRESS;

const auctionInit = {
timestamp: _auctionStart,
auctionId: _auctionId,
timeout: _timeout
};
events.emit(CONSTANTS.EVENTS.AUCTION_INIT, auctionInit);

let callbacks = auctionCallbacks(auctionDone, this);
let boundObj = {
auctionAddBidResponse: callbacks.addBidResponse
}
adaptermanager.callBids(_adUnits, bidRequests, addBidResponse.bind(boundObj), callbacks.adapterDone, {
request(source, origin) {
increment(outstandingRequests, origin);
increment(requests, source);

if (!sourceInfo[source]) {
sourceInfo[source] = {
SRA: true,
origin
};
}
if (requests[source] > 1) {
sourceInfo[source].SRA = false;
}
},
done(origin) {
outstandingRequests[origin]--;
if (queuedCalls[0]) {
if (runIfOriginHasCapacity(queuedCalls[0])) {
queuedCalls.shift();
if (bidRequests.length < 1) {
utils.logWarn('No valid bid requests returned for auction');
} else {
let call = {
bidRequests,
run: () => {
startAuctionTimer();

_auctionStatus = AUCTION_IN_PROGRESS;

const auctionInit = {
timestamp: _auctionStart,
auctionId: _auctionId,
timeout: _timeout
};
events.emit(CONSTANTS.EVENTS.AUCTION_INIT, auctionInit);

let callbacks = auctionCallbacks(auctionDone, this);
let boundObj = {
auctionAddBidResponse: callbacks.addBidResponse
};
adaptermanager.callBids(_adUnits, bidRequests, addBidResponse.bind(boundObj), callbacks.adapterDone, {
request(source, origin) {
increment(outstandingRequests, origin);
increment(requests, source);

if (!sourceInfo[source]) {
sourceInfo[source] = {
SRA: true,
origin
};
}
if (requests[source] > 1) {
sourceInfo[source].SRA = false;
}
},
done(origin) {
outstandingRequests[origin]--;
if (queuedCalls[0]) {
if (runIfOriginHasCapacity(queuedCalls[0])) {
queuedCalls.shift();
}
}
}
}
}, _timeout);
}
};
}, _timeout);
}
};

if (!runIfOriginHasCapacity(call)) {
utils.logWarn('queueing auction due to limited endpoint capacity');
queuedCalls.push(call);
if (!runIfOriginHasCapacity(call)) {
utils.logWarn('queueing auction due to limited endpoint capacity');
queuedCalls.push(call);
}
}

function runIfOriginHasCapacity(call) {
Expand Down
71 changes: 51 additions & 20 deletions src/sizeMapping.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { config } from 'src/config';
import { logWarn } from 'src/utils';
import {logWarn, isPlainObject, deepAccess, deepClone} from 'src/utils';
import includes from 'core-js/library/fn/array/includes';

let sizeConfig = [];
Expand Down Expand Up @@ -29,36 +29,67 @@ config.getConfig('sizeConfig', config => setSizeConfig(config.sizeConfig));
* @param {Array<string>} labels Labels specified on adUnit or bidder
* @param {boolean} labelAll if true, all labels must match to be enabled
* @param {Array<string>} activeLabels Labels passed in through requestBids
* @param {Array<Array<number>>} sizes Sizes specified on adUnit
* @param {object} mediaTypes A mediaTypes object describing the various media types (banner, video, native)
* @param {Array<Array<number>>} sizes Sizes specified on adUnit (deprecated)
* @param {Array<SizeConfig>} configs
* @returns {{labels: Array<string>, sizes: Array<Array<number>>}}
*/
export function resolveStatus({labels = [], labelAll = false, activeLabels = []} = {}, sizes = [], configs = sizeConfig) {
export function resolveStatus({labels = [], labelAll = false, activeLabels = []} = {}, mediaTypes, sizes, configs = sizeConfig) {
let maps = evaluateSizeConfig(configs);

let filteredSizes;
if (maps.shouldFilter) {
filteredSizes = sizes.filter(size => maps.sizesSupported[size]);
if (!isPlainObject(mediaTypes)) {
mediaTypes = {};
} else {
filteredSizes = sizes;
mediaTypes = deepClone(mediaTypes);
}

return {
active: filteredSizes.length > 0 && (
labels.length === 0 || (
(!labelAll && (
labels.some(label => maps.labels[label]) ||
labels.some(label => includes(activeLabels, label))
)) ||
(labelAll && (
labels.reduce((result, label) => !result ? result : (
maps.labels[label] || includes(activeLabels, label)
), true)
))
// add support for deprecated adUnit.sizes by creating correct banner mediaTypes if they don't already exist
if (sizes) {
if (!mediaTypes.banner) {
mediaTypes.banner = {
sizes
}
} else if (!mediaTypes.banner.sizes) {
mediaTypes.banner.sizes = sizes;
}
}

let oldSizes = deepAccess(mediaTypes, 'banner.sizes');
if (maps.shouldFilter && oldSizes) {
mediaTypes.banner.sizes = oldSizes.filter(size => maps.sizesSupported[size]);
}

let allMediaTypes = Object.keys(mediaTypes);

let results = {
active: (
allMediaTypes.length > 1 || (allMediaTypes.length === 1 && allMediaTypes[0] !== 'banner')
) || (
allMediaTypes[0] === 'banner' && deepAccess(mediaTypes, 'banner.sizes.length') > 0 && (
labels.length === 0 || (
(!labelAll && (
labels.some(label => maps.labels[label]) ||
labels.some(label => includes(activeLabels, label))
)) ||
(labelAll && (
labels.reduce((result, label) => !result ? result : (
maps.labels[label] || includes(activeLabels, label)
), true)
))
)
)
),
sizes: filteredSizes
mediaTypes
};

if (oldSizes && oldSizes.length !== mediaTypes.banner.sizes.length) {
results.filterResults = {
before: oldSizes,
after: mediaTypes.banner.sizes
}
}

return results;
}

function evaluateSizeConfig(configs) {
Expand Down
Loading

0 comments on commit a680824

Please sign in to comment.