-
Notifications
You must be signed in to change notification settings - Fork 753
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
Changes from 4 commits
b735807
7bf0358
e617bd2
be41c4b
925cc9f
2528a08
20d6f7f
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 |
---|---|---|
|
@@ -56,9 +56,10 @@ func NewFetcher(client *http.Client, endpoint string) *HttpFetcher { | |
} | ||
|
||
type HttpFetcher struct { | ||
client *http.Client | ||
Endpoint string | ||
hasQuery bool | ||
client *http.Client | ||
Endpoint string | ||
hasQuery bool | ||
Categories map[string]map[string]stored_requests.Category | ||
} | ||
|
||
func (fetcher *HttpFetcher) FetchRequests(ctx context.Context, requestIDs []string, impIDs []string) (requestData map[string]json.RawMessage, impData map[string]json.RawMessage, errs []error) { | ||
|
@@ -80,8 +81,48 @@ func (fetcher *HttpFetcher) FetchRequests(ctx context.Context, requestIDs []stri | |
return | ||
} | ||
|
||
func (fetcher *HttpFetcher) FetchCategories(primaryAdServer, publisherId, iabCategory string) (string, error) { | ||
return "", nil | ||
func (fetcher *HttpFetcher) FetchCategories(ctx context.Context, primaryAdServer, publisherId, iabCategory string) (string, error) { | ||
if fetcher.Categories == nil { | ||
fetcher.Categories = make(map[string]map[string]stored_requests.Category) | ||
} | ||
|
||
//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 "?" | ||
url := fmt.Sprintf("%s/%s.json", strings.Replace(fetcher.Endpoint, "?", "", -1), primaryAdServer) | ||
|
||
dataName := primaryAdServer | ||
|
||
if publisherId != "" { | ||
dataName = fmt.Sprintf("%s_%s", primaryAdServer, publisherId) | ||
url = fmt.Sprintf("%s/%s/%s.json", strings.Replace(fetcher.Endpoint, "?", "", -1), primaryAdServer, publisherId) | ||
} | ||
|
||
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 commentThe 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 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. @mansinahar yes, it's good to have this check. Thank you! 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. Thanks @Kalypsonika ! |
||
} | ||
|
||
httpReq, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
httpResp, err := ctxhttp.Do(ctx, fetcher.client, httpReq) | ||
if err != nil { | ||
return "", err | ||
} | ||
defer httpResp.Body.Close() | ||
|
||
respBytes, err := ioutil.ReadAll(httpResp.Body) | ||
tmp := make(map[string]stored_requests.Category) | ||
|
||
if err := json.Unmarshal(respBytes, &tmp); err != nil { | ||
return "", fmt.Errorf("Unable to unmarshal categories for adserver: '%s', publisherId: '%s'", primaryAdServer, publisherId) | ||
} | ||
fetcher.Categories[dataName] = tmp | ||
|
||
resultCategory := tmp[iabCategory].Id | ||
|
||
return resultCategory, nil | ||
} | ||
|
||
func buildRequest(endpoint string, requestIDs []string, impIDs []string) (*http.Request, error) { | ||
|
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!
We don't expect to have URL with parameters for http fetcher, here is how url builder looks like:
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:
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 tostrings.TrimSuffix
.Refactoring existing code in
NewFetcher
is beyond the scope of this PR and will require to refactorbuildRequest
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