-
Notifications
You must be signed in to change notification settings - Fork 741
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
Implementation of Categories Http fetcher #882
Conversation
-Added code to fetch data using http -Added previously loaded categories to run http request just at the first time
client *http.Client | ||
Endpoint string | ||
hasQuery bool | ||
Categories map[string]map[string]file_fetcher.Category |
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.
We should move the file_fetcher.Category type into a common module so that http_fetcher doesn't have to depend on file_fetcher.
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.
Agree. Done
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.
It mostly looks fine to me, just a couple of minor issues I commented on that should be addressed before we merge. Thanks.
return data[iabCategory].Id, nil | ||
} | ||
|
||
url := fmt.Sprintf("%s/%s/%s.json", strings.Replace(fetcher.Endpoint, "?", "", -1), primaryAdServer, publisherId) |
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.
Probably just removing the ? isn't going to work if the fetcher.Endpoint contains query params in the URL, we should just have this function throw an appropriate error if the endpoint has a ? here (instead of trying to handle that case).
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.
I made it because in NewFetcher
function contains this code:
func NewFetcher(client *http.Client, endpoint string) *HttpFetcher {
// Do some work up-front to figure out if the (configurable) endpoint has a query string or not.
// When we build requests, we'll either want to add `?request-ids=...&imp-ids=...` _or_
// `&request-ids=...&imp-ids=...`, depending.
urlPrefix := endpoint
if strings.Contains(endpoint, "?") {
urlPrefix = urlPrefix + "&"
} else {
urlPrefix = urlPrefix + "?"
}
...
return &HttpFetcher{
client: client,
Endpoint: urlPrefix,
}
}
because of this there is always ?
at the end of url.
In my understanding in case of Categories fetcher we expect to have url without parameters, so I have to handle this explicitly.
Do you think I need to refactor existing functionality?
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.
Oh ok I see why that's there then. I guess the difference is category fetcher is expecting it's variable parts to be in the URL path where as other fetchers are passing them in URL query params. Maybe this is fine then, but please add a comment to the effect that you are stripping away the question mark that gets added in NewFetcher code. Also we're assuming endpoints used for category mappings aren't going to contain query params, which maybe is ok since they'll probably just be statically hosted files.
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.
Comment added.
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.
Looks good to me
} | ||
|
||
if publisherId == "" { | ||
publisherId = primaryAdServer |
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 means we could have something like freewheel_freewheel
as the dataName
below. Is this correct, or should it resolve to just freewheel
?
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, fixed!
} | ||
|
||
if data, ok := fetcher.Categories[dataName]; ok { | ||
return data[iabCategory].Id, nil |
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.
Overall the PR LGTM. I just have one small question though: Are we sure that the data
will always have a value for iabCategory
? Should we rather just do a small check before we return? Both here and towards the end of the function.
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.
@mansinahar yes, it's good to have this check. Thank you!
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.
Thanks @Kalypsonika !
-Added verification if category exist in map
} | ||
|
||
//in NewFetcher function there is a code to add "?" at the end of url | ||
//in case of categories we don't expect to have any parameters, that's why we need to remove "?" |
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.
A few comments about this code:
-
NewFetcher() is capable of returning "&" as the last character as well as "?" (in which case there will be a "?" somewhere earlier in the string). I'm guessing from the above comment that this will never happen for categories. Is that correct? If so, might it be better (i.e., probably more efficient and more readable) to use strings.TrimSuffix() to simply remove the "?" from the end of the string? If "?" is not guaranteed to be at the end of the string, then shouldn't everything from the "?" in the line forward be removed? It might be safest to allow for the possibility of "?" not being at the end of the line (in case of future changes) and use strings.IndexByte() to find the "?" and chop off the end of the line from there; this works regardless of the location of "?".
-
The url variable is assigned twice when publisherId has a value, both times making the same call to strings.Replace(). The data name variable is also assigned a value twice. It would be a little more efficient to simply declare url and dataName as strings, then use an if-statement to assign each variable once.
-
Taking efficiency considerations to an extreme, if it's likely that fetcher.Categories[dataName] is likely to be set more often than not (I don't know how one would know this), it might be even more efficient to put off setting the value of url until it is needed, in case we never get there. Drawback to this is it's less efficient (two if-statements needed to check publisherId) when fetcher.Categories[dataName] is unset.
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.
Hi Joe, @josephveach thank you for your comment!
- Please see above discussion with Jason about this. There is a code snipped with logic of adding "?" at the end of URL: Implementation of Categories Http fetcher #882 (comment)
We don't expect to have URL with parameters for http fetcher, here is how url builder looks like:
url = fmt.Sprintf("%s/%s/%s.json", strings.Replace(fetcher.Endpoint, "?", "", -1), primaryAdServer, publisherId)
-
Refactored
-
URL builder is just a simple string concatenation. We can separate it and have 2 publisher id checks. I would leave it as it is now.
Please let me know what do you think.
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.
Hi Veronika, Let me clarify my thoughts regarding (1):
Looking purely at the NewFetcher() code, it seems that the returned value of Endpoint can be in two forms:
(a) if there is no query string in the original "endpoint" argument to NewFetcher() (i.e., endpoint was of form someURL), then Endpoint is simply
someURL?
which works fine with the given code, but
(b) if "endpoint" contained a query string, i.e., was of form someURL?someQuery, then Endpoint would be
someURL?someQuery&
which I believe does not work properly with the given code.
The comment simply states "we don't expect to have any parameters" in the category case, which does not seem absolute or clear to me (e.g., does "don't expect" mean it's impossible? does "parameters" equate to what would be in the query?). Furthermore, as I've already indicated, the use of strings.Replace() probably doesn't achieve the desired effect on the second form (b) above of the returned value of Endpoint.
IMHO, it would be more clear to someone who is not terribly familiar with the underlying code that gets us here if (1) this code used strings.TrimSuffix() instead of strings.Replace(), which would emphasize the '?' occurs only as the last character and, possibly, (2) if the comment were a little more strong, i.e., something like "in case of categories, there is never a query string in the endpoint so it always ends with '?'", which is more certain than "we don't expect". Actually, looking at previous discussion, I prefer Jason's explanation above: "category fetcher is expecting its variable parts to be in the URL path whereas other fetchers are passing them in URL query params", though maybe "expecting" could be replaced by something stronger in a code comment.
I also expect strings.TrimSuffix() to run faster than strings.Replace() because it doesn't need to examine the entire string, though I haven't confirmed that.
BTW, I see that NewFetcher() also does an unnecessary second assignment to urlPrefix. The first portion of the function could be changed to simply:
var urlPrefix string
if strings.Contains(endpoint, "?") {
urlPrefix = endpoint + "&"
} else {
urlPrefix = endpoint + "?"
}
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.
Hi Joe, strings.Replace
is changed to strings.TrimSuffix
.
Refactoring existing code in NewFetcher
is beyond the scope of this PR and will require to refactor buildRequest
function as well.
Also there are no specific requirements to categories URL, so maybe url builder will be changed in future.
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.
My original comment suggested to chop off the end of the line starting at the "?" if there was a chance of the "?" ever not being the last character. You seem to be saying that could be a possibility in the future, in which case this solution could lead to a problem at that time. In any case, I've made my suggestion and I have no other objections so I'll give my approval of the PR.
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.
Thank you Joe!
With current implementation we just want to delete last "?". If it's not there - url is returned unchanged. Please see this documentation: https://golang.org/pkg/strings/#TrimSuffix
-strings.Replace changed to strings.TrimSuffix
} | ||
|
||
//in NewFetcher function there is a code to add "?" at the end of url | ||
//in case of categories we don't expect to have any parameters, that's why we need to remove "?" |
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.
My original comment suggested to chop off the end of the line starting at the "?" if there was a chance of the "?" ever not being the last character. You seem to be saying that could be a possibility in the future, in which case this solution could lead to a problem at that time. In any case, I've made my suggestion and I have no other objections so I'll give my approval of the PR.
* Use the correct labels for cache performance metric (prebid#904) * PubMatic Adslot validation (prebid#886) * testing a few changes to validate adslot, more to follow * Changed AdSlot to optional parameter, modified validation and test cases for the same * removed imp id from adslot validation error msgs * assign banner size * remove TrimSpace where it is not needed as recommended in the review * Implementation of Categories Http fetcher (prebid#882) * Implementation of Categories Http fetcher -Added code to fetch data using http -Added previously loaded categories to run http request just at the first time * Moved common Category struct to stored_request * Added comments * Minor refactoring * Minor refactoring -Added verification if category exist in map * Minor refactoring * Minor refactoring -strings.Replace changed to strings.TrimSuffix * Improved error handling on Beachfront adapter (prebid#873) * Removed a redundant error message that was causing some confusion. * trying to turn '[]' into null and 200 inti 404 * not a goot path * looking at the status codes * I think I have covers all these bases. * checking for empty array response a failing sanely * removed an attempt to pointlessly reset the status code. * corrected and added test cases * Fix Rubicon bidder for multi-format impression processing (prebid#902) * Replace Dockerfile Alpine linux with Ubuntu (prebid#885) * Ubuntu dockerfile works, includes backups and out file * Ubuntu Dockerfile creates image successfully and prebid-server was tested with a sample request. Seems to work fine * Ubuntu 18.04 now builds, validates.sh, and curls sample request successfully * Removed sed command * [fix] broken Go 1.9 compatibility (prebid#910) This CL addresses Go 1.9 compatibility issue along with adding back Go 1.9 to travis testing setup to prevent such bugs. Issue: prebid#895 * Fixed "invalid BidType: " error for lifestreet adapter (prebid#893) * Fixed "invalid BidType: " error for lifestreet adapter * After run gofmt * Used standard bid.ext type to get bid.ext.prebid.type * [Currency support] Activate multi-currencies support (prebid#894) This CL is the last piece to activate currency conversion support in PBS. It activates currency support per default. Currency rates will be fetched once per hour (PrebidJS file is updated once a day). Issue: prebid#280 * ImproveDigital adapter: (prebid#887) - Add support for video - Add support for mobile/app - Add support for multibid responses - Extend optional parameters * Add a PI exemption environment variable to PBS (prebid#916) * Refactored to official name of config item * Changes suggested by Mansi Nahar * [Sharethrough] Add new Sharethrough Adapter (prebid#903) * wip * wip * wip * exploration for sharethrough prebid-server * WIP: updating sharethrough adapter to latest prebid version Co-authored-by: Chris Nguyen <[email protected]> * WIP: adding butler params to the request #164291358 Co-authored-by: Josh Becker <[email protected]> * Manage bid sizes [#164291358] Co-authored-by: Josh Becker <[email protected]> * Manage GDPR [#164291358] Co-authored-by: Josh Becker <[email protected]> * Populate prebid-server version if provided [#164291358] Co-authored-by: Josh Becker <[email protected]> * Refactor gdpr data extraction from request [#164291358] Co-authored-by: Eddy Pechuzal <[email protected]> * Add instant play capability [#164291358] Co-authored-by: Eddy Pechuzal <[email protected]> * Split in multiple files [#164291358] Co-authored-by: Eddy Pechuzal <[email protected]> * Add s2s-win beacon todo? replace server name by server id? [#164291358] Co-authored-by: Eddy Pechuzal <[email protected]> * Removing `server` param in s2s-win beacon (will be added in imp req) [#164291358] * Clean up code + enable syncer (prebid#4) [#165257793] * Proper error handling (prebid#6) * Proper error handling [#165745574] * Address review (baby clean up) + catch error that was missed [#165745574] * Implement Unit Tests (prebid#7) * Proper error handling [#165745574] * Address review (baby clean up) + catch error that was missed [#165745574] * Implement unit tests for utils [#165891351] * Add UT for utils + butler [#165891351] Co-authored-by: Michael Duran <[email protected]> * Attempt for testing Bidder interface function implementations [#165891351] Co-authored-by: Michael Duran <[email protected]> * Finalizing Unit tests [#165891351] Co-authored-by: Chris Nguyen <[email protected]> Co-authored-by: Josh Becker <[email protected]> * Fixing sharethrough.yaml capabilities [#165891351] Co-authored-by: Josh Becker <[email protected]> * Send supplyId to imp req instead of hbSource (prebid#5) [#165477915] * Finalize PR (prebid#8) [#164911891] Co-authored-by: Josh Becker <[email protected]> * Remove test setting * Add Sharethrough in syncer_test * Update deserializing of third party partners * Refactor/optimize UserAgent parsing (prebid#9) following josephveach's review in prebid#903 * Addressing June 3rd review from prebid#903 Optimizations, clean up suggested by @mansinahar * Addressing June 4th review from prebid#903 (prebid#10) * Addressing June 4th review from prebid#903 Clean up canAutoPlayVideo + hardcode bhVersion to unknown for now... * Removing hbVersion butler param since it's not accessible * Fix adMarkup error handling * [Mgid] Add new Mgid Adapter (prebid#907) * new mgid adapter * increase coverage * remove extra imports * Cache validation fix (prebid#911) * Cache validation fix if no bids returned - don't throw cache error, just return empty result * Cache validation fix - optimization: do not run auction logic if no bids returned * Cache validation fix: minor refactoring * Cache validation fix: minor refactoring * Cache validation fix: added unit test for no bids returned * Cache validation fix: minor refactoring * Remove hard coded targeting keys (prebid#923)
* Implementation of Categories Http fetcher -Added code to fetch data using http -Added previously loaded categories to run http request just at the first time * Moved common Category struct to stored_request * Added comments * Minor refactoring * Minor refactoring -Added verification if category exist in map * Minor refactoring * Minor refactoring -strings.Replace changed to strings.TrimSuffix
* Implementation of Categories Http fetcher -Added code to fetch data using http -Added previously loaded categories to run http request just at the first time * Moved common Category struct to stored_request * Added comments * Minor refactoring * Minor refactoring -Added verification if category exist in map * Minor refactoring * Minor refactoring -strings.Replace changed to strings.TrimSuffix
* Implementation of Categories Http fetcher -Added code to fetch data using http -Added previously loaded categories to run http request just at the first time * Moved common Category struct to stored_request * Added comments * Minor refactoring * Minor refactoring -Added verification if category exist in map * Minor refactoring * Minor refactoring -strings.Replace changed to strings.TrimSuffix
-Added code to fetch data using http
-Added previously loaded categories to run http request just at the first time