Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Implement proxy mode #860
Implement proxy mode #860
Changes from all commits
05cb854
afeca96
197142a
a55148e
dfc4415
47a6258
fadd019
bafeddd
c1ea538
2d7c68f
31eae5a
682bd8c
0c56249
2e976e7
ab65cc0
65fff2f
8a2cc96
c139e98
8154c39
3acc0f8
0bf150c
0286b08
c699482
7570c17
529f0b3
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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 don't like so much that we need to add logic to all handlers for the proxy mode.
I guess that another option would be to implement it as an indexer, but as indexers are now we would be making unneeded calls to the remote registry if there is already a local package that matches. Is this the reason to don't use indexers?
Maybe a way to overcome this could be to add to the indexer interface a
GetFirst() (*packages.Package, error)
method, that could be used by indexers to optimize the [several] cases where we only want the first package. Most indexers would implementGetFirst()
as returning the first package in the result ofGet()
, but theCombinedIndexer
could implement it as breaking the loop once it finds a package in one indexer.Or a similar approach would be to add a new
MaxResults
option toGetOptions
, to return only the first n packages found. But an option can be ignored/forgotten, while a method in the interface needs to be implemented.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 analyzed this case. If we want to implement an indexer then we will have to call the search endpoint (with
all=true
) on every API call. Responses would be heavy and heavier in the future. I wouldn't like to implement an artificial cache that syncs periodically with the remote Package Registry, but I'm happy to discuss other options.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.
Would this still be true with the
GetFirst()
approach? The logic would be similar to what is done here in each handler, but it would be centralized in theCombinedIndexer
: it would return the first package found without needing to look for all indexers, so it wouldn't call the proxy for packages available locally. And when it calls the proxy, it would be with the parameters of the request, not withall=true
.Another advantage of using an indexer is that we can add it only when the feature is enabled, without needing to check on every call if the proxy is enabled.
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.
Don't get me wrong, I'd love to use a dedicated indexer here, but I'm not sure if it's possible to apply the concept here.
The problem with an indexer is that it isn't aware of the calling context and it can't return correct/full package metadata. Consider following flows:
Search packages:
indexer.Get(options)
:1.1 Mashal the filter to query.
1.2 Make a call
/search?all=true
(heavy HTTP response)1.3 Apply the filter.
1.4 Fill private (
fsBuilder
,resolver
,semver
) or skipped fields (BasePath
)Problem: Unfortunately, returned packages don't contain all properties of policy templates (Package vs BasePackage), so the result returned by indexer is always incorrect.
Package resources/signature:
indexer.Get(options)
:1.1 Mashal the filter to query - based on the filter we should figure out to which endpoint we should proxy request?
1.2 Make a call, for example: /package/apm/8.4.0/
1.3 Apply the filter.
1.4 Fill private (
fsBuilder
,resolver
,semver
) or skipped fields (BasePath
)Categories:
indexer.Get(options)
:1.1 Mashal the filter to query.
1.2 Make a call
/search?all=true
(heavy HTTP response)...
Problem: Now, we need to pull all packages to map them into categories. We need to visit also categories in policy templates, BUT the
/search
endpoint don't expose them (all categories are group together incategories: [ ... ]
. For the sake of/categories
, we could use those buggy packages, but they would work accidentally (we don't analyze policy templates).I might have missed something while I tried to implement this approach. Feel free to share your thoughts!
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.
Yeah, it is a bit beyond of their concept to use indexers for this. More than specifically using them, I was wondering about a way to separate more the proxy mode without needing to modify all the handlers, so when disabled no additional code is executed.
To search packages I don't think that we would need to search all and filter, we could translate the
options.Filter
into an equivalent search query, and wouldn't be needed to filter afterwards. From the result the private fields would be filled as they are now in this PR. https://github.com/elastic/package-registry/pull/860/files#diff-d3d83ca5e1802bcf5d721013c2c366abb0d682c3e100e4307630c34f85cf6f89R93-R100Though for categories it is true that we would need to search for all packages, and even this could be inaccurate as you mention.
Two more ideas to separate the proxy mode:
But we can continue with the current approach, every option seems to have its cons. Thanks for the discussion!