-
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
Prebid Core: Allow Cpm Custom Rounding #9018
Conversation
I'll link doc changes when I have them |
Looks fine to me, my only question is that if we should put some protection around the customFunction? Maybe a What do you think @dgirardi |
That makes sense to me. I'm guessing a lot of pubs are going to end up calling their rounding function when they try to set it. I'll get that pushed up shortly |
let expected = '{"low":"5.00","med":"6.50","high":"6.51","auto":"6.50","dense":"6.50","custom":"6.50"}'; | ||
let output = getPriceBucketString(cpm, customConfig); | ||
config.getConfig = getConfig; | ||
expect(JSON.stringify(output)).to.deep.equal(expected); |
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.
Maybe a test case that also handles if they DO pass a function but the function itself throws an error.
I think the case here actually is testing this part:
let roundingFunction = Math.floor;
let customRoundingFunction = config.getConfig('cpmRoundingFunction');
if (typeof customRoundingFunction === 'function') {
roundingFunction = customRoundingFunction;
}
since config.getConfig = () => Math.ceil(5.3)
will just return 6.0 not a function.
So typeof customRoundingFunction === 'function'
will be false so it will keep default of Math.floor
So another test which does something like:
config.getConfig = () => () => {
throw new Error('I am an error');
}
So it actually sets roundingFunction
to the input customRoundingFunction
and tries to execute it, but since it throws an error, it uses Math.floor
try { | ||
cpmTarget = (roundingFunction(cpmToRound) * increment) + bucketMin; | ||
} catch (err) { | ||
cpmTarget = (Math.floor(cpmToRound) * increment) + bucketMin; |
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.
Should we log a warning here so easier to debug when this exception occurs?
@@ -118,17 +119,35 @@ function getCpmTarget(cpm, bucket, granularityMultiplier) { | |||
const precision = typeof bucket.precision !== 'undefined' ? bucket.precision : _defaultPrecision; |
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.
This change LGTM, but isn't the use case for this already covered by this configurable precision
(as explained here)? This is probably more about documentation, it's not clear to me why I'd want to use one over the other.
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.
Precision states where the rounding will occur, but the rounding is always down. This change allows for other rounding methods.
e.g.
Current
cpm = 2.1456, increment = .05, precision = 3
precise cpm = 2.145, rounded down to nearest increment = 2.10
Final result = 2.100
With alternate rounding
cpm = 2.1456, increment = 0.5 precision = 4
precise cpm = 2.1456, rounded with Math.round to nearest increment = 2.15
Final result = 2.1500
At least, that's how I understand it. As far as I can tell, the precision determines what is being rounded down, but it is always rounded down, and always to the nearest increment, which in effect just tacks extra zeroes to the end of the result.
Then again, I'm mostly basing that off the unit tests, which aren't super comprehensive for precision, and the documentation, which only shows the default of 2. If precision is supposed to affect rounding in any way, I don't get it. As long as the precision is greater than or equal to the number of decimal places in the increment, rounding will be unaffected by precision, which makes this change useful.
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're right, I thought you could get the equivalent of Math.round
by increasing the precision by 1, but that's not exactly what happens.
If you round up, what happens if someone bids 50000.00 usd for example. Please add a unit test to demonstrate this is handled and discuss in documentation bids over the top value. |
I don't really understand what the requested unit test and docs changes have to do with this change. That behavior is entirely unaffected. As noted in the comment on line 85 (now 86), if the bid exceeds the cap, the cap will be returned. It will do so without ever touching this change. Even if it were related, the current unit tests cover this sufficiently, as the cap is returned for the low price config in the custom rounding function unit test. |
@patmmccann What's your take? I haven't worked with the bucket manager before, so I wouldn't be shocked if I missed something. Do you think more unit tests/documentation is needed here? |
* Allow custom rounding functions * Add custom rounding unit tests * Default to Math.floor when passed an invalid rounding function * Add error logging * Fix import statement
* Allow custom rounding functions * Add custom rounding unit tests * Default to Math.floor when passed an invalid rounding function * Add error logging * Fix import statement
For any user facing change, submit a link to a PR on the docs repo at https://github.com/prebid/prebid.github.io/
-->
Type of change
Description of change
Allow publishers to set their own rounding rules as desired
Other information
@robertrmartinez