-
Notifications
You must be signed in to change notification settings - Fork 142
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
Update review list right after user posting/revoking #670
Conversation
Thanks for your contribution @yiningwang11. It works as expected. I think it would be better to use the ETag header instead of fixed duration caching or no caching at all. It's a combination of creating an ETag of the JSON response: openvsx/server/src/main/java/org/eclipse/openvsx/web/ShallowEtagHeaderFilter.java Lines 17 to 30 in 962947c
caching the response: openvsx/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java Lines 109 to 116 in 962947c
and evicting the cache at the right time:
|
Thank you for your suggestion. I'll continue look into it :) |
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.
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.
@@ -750,7 +750,7 @@ public ResponseEntity<SearchResultJson> search( | |||
} | |||
|
|||
return ResponseEntity.ok() | |||
.cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic()) | |||
.cacheControl(CacheControl.noCache().cachePublic()) |
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 wonder if there is a better way of replacing the cache instead of disabling it altogether? cc @amvanbaren
Otherwise I'm good with the changes
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 wonder if there is a better way of replacing the cache instead of disabling it altogether?
Yes, a combination of server caching and generating an ETag for the response. If the request contains the If-None-Match
header and the value matches the ETag value, then no content (204) is returned because the client already has the most up to date response. #670 (comment)
@@ -16,16 +16,12 @@ public class ShallowEtagHeaderFilter extends org.springframework.web.filter.Shal | |||
|
|||
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { | |||
// limit the filter to /api/{namespace}/{extension}, /api/{namespace}/details | |||
// and /api/{namespace}/{extension}/{version} endpoints | |||
// and /api/{namespace}/{extension}/{version}, and /api/-/search endpoints |
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.
@yiningwang11 Why generate an ETag for the /api/-/search
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, @amvanbaren thanks for the review!
I added this to generate an ETag for the response because I have disabled the cache for the search endpoint that returns the homepage. I thought with an ETag coming with the response header, even though the cache is disabled, no content would still be returned if the client has the up-to-date response.
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.
@yiningwang11 Ok, that's true. The downside is that the search is fully processed. Only at the end the ShallowEtagHeaderFilter
compares the If-None-Match
request header with the hash of the JSON body and discards the body if the two Etags match.
On the other hand #542 caches search results on the server side, so this approach will work. I'll test #542 and merge it in.
@@ -111,7 +111,9 @@ public ExtensionJson getExtension(String namespace, String extensionName, String | |||
public ExtensionJson getExtension(String namespace, String extensionName, String targetPlatform, String version) { | |||
var extVersion = findExtensionVersion(namespace, extensionName, targetPlatform, version); | |||
var json = toExtensionVersionJson(extVersion, targetPlatform, true, false); | |||
var extension = repositories.findExtension(extensionName, namespace); |
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.
Please remove this statement, because you don't have to set averageRating
here.
json.downloads = getDownloads(extVersion.getExtension(), targetPlatform, extVersion.getVersion()); | ||
json.averageRating = extension.getAverageRating(); |
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.
Please remove this statement, because averageRating
is already set in ExtensionVersion.toExtensionJson
.
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.
Hello @amvanbaren , thanks for your comment!
The reason that I set averageRating
here is because I found out in ExtensionVersion.toExtensionJson
, the averageRating is not updated immediately according to deleting/posting new reviews with new ratings of an extension. However, the extension.averageRating
is being updated correctly in time. That's why I put an extra statement here to update the averageRating
.
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.
Ok, I see what you mean. I went through the code to find out how this could happen. The VersionService
caches the latest ExtensionVersion
. When a review is posted or deleted your fork doesn't evict the latest version cache, which causes findExtensionVersion
to return a cached instance of the lastest ExtensionVersion
with an old Extension
instance (averageRating
not updated).
This has been fixed in master
. Can you sync your master
branch and rebase the updateReview
branch? Then the extra database call shouldn't be necessary anymore.
You can sync the master
branch by clicking Sync fork
in the right corner of your Github repo:
After syncing your fork you can rebase by opening a terminal in your openvsx directory and following these steps:
git checkout master
git pull
git checkout updateReview
git rebase master
<FIX CONFLICTS & COMMIT>
git rebase --continue
git push -f origin updateReview
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.
Hello @amvanbaren , thanks for your suggestion!
I've followed these commands but seems like git push -f origin updateReview
has caused one of the checks to be failing. It looks like one of the authors of the commits is not covered by the ECA. I'm not sure if that's gonna affect anything, or what should I do to fix this?
Thank you again for your help :)
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 @yiningwang11, it looks like you merged openvsx:master
on top of your updateReview
branch. yiningwang11:master
is still 70 commits behind eclipse:master
.
A rebase changes the base of the branch, but the changes you've made stay on top. This article explains it in further detail: https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase. The example under the Usage heading describes what we try to do here.
Are the top 5 commits for this feature or were there more commits?
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.
Hello @amvanbaren , thanks for your comment! I went over the article you recommended. Is this because I should have sync my yiningwang11:master
branch and then rebase the updateReview
feature branch, instead of merge the openvsx:master
on top of my updateReview
feature branch?
Is there anything I can do to make things right at the moment?
The top 5 commits in the screenshot you shared were for this feature, there aren't any more commits yet. (I'm still working on adding the @Cacheable
annotation on LocalRegistryService.getReviews
now)
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.
Is this because I should have sync my yiningwang11:master branch and then rebase the updateReview feature branch, instead of merge the openvsx:master on top of my updateReview feature branch?
Yes, it is so that this feature is current with master
. This ensures that you don't run into issues that already have been fixed in master
and that there are no conflicts when this branch is merged into master
.
Is there anything I can do to make things right at the moment?
Yes, you can use git rebase
to drop the unwanted commits.
First, do git stash
to store your current changes.
Then set VS Code as your default git editor. You can skip this step if you're familiar with vim.
git config core.editor "code --wait"
Next, do an interactive rebase on your updateReview
branch. I see this PR has 46 commits. If you have more commits locally then increase the number in the below command, e.g. you've added 2 more commits, then the number becomes 48.
git rebase -i HEAD~46
You get a list of commits. You need to keep the first 5 commits and if you've added extra commits since this PR you want to keep those too. All the other commits in between you want to drop.
When you're 100% sure (you can't undo this operation) which commits to keep and which to drop, close the editor. The rebase is applied and the commits from the merge with master
should be gone.
Force push updateReview
git push -f origin updateReview
If you used git stash
, you can use git stash apply
to get your local working changes back.
@@ -777,6 +779,7 @@ private List<SearchEntryJson> toSearchEntries(SearchHits<ExtensionSearch> search | |||
.map(e -> { | |||
var entry = e.getValue().toSearchEntryJson(); | |||
entry.url = createApiUrl(serverUrl, "api", entry.namespace, entry.name); | |||
entry.averageRating = repositories.findExtension(entry.name, entry.namespace).getAverageRating(); |
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.
Please remove this statement, because averageRating
is already set in ExtensionVersion.toSearchEntryJson
.
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 added this statement due to the same reason. I found ExtensionVersion.toSearchEntryJson
is not updating averageRating
attribute according to deleting/posting reviews with new ratings.
@@ -16,16 +16,12 @@ public class ShallowEtagHeaderFilter extends org.springframework.web.filter.Shal | |||
|
|||
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { | |||
// limit the filter to /api/{namespace}/{extension}, /api/{namespace}/details | |||
// and /api/{namespace}/{extension}/{version} endpoints | |||
// and /api/{namespace}/{extension}/{version}, and /api/-/search endpoints |
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.
@yiningwang11 Ok, that's true. The downside is that the search is fully processed. Only at the end the ShallowEtagHeaderFilter
compares the If-None-Match
request header with the hash of the JSON body and discards the body if the two Etags match.
On the other hand #542 caches search results on the server side, so this approach will work. I'll test #542 and merge it in.
@@ -632,7 +632,7 @@ public ResponseEntity<ReviewListJson> getReviews( | |||
for (var registry : getRegistries()) { | |||
try { | |||
return ResponseEntity.ok() | |||
.cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic()) | |||
.cacheControl(CacheControl.noCache().cachePublic()) |
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.
@yiningwang11 Can you also make LocalRegistryService.getReviews
@Cacheable
? Please make sure to evict entries from the cache when a review is added (LocalRegistryService.postReview
) or deleted (LocalRegistryService.deleteReview
) and when UserData
changes in UserService.updateExistingUser
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.
@amvanbaren I'll take a look into this. Thank you!
} | ||
if(applyFilter && path.length == 4) { | ||
applyFilter = !(path[3].equals("review") || path[3].equals("reviews")); |
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.
Please keep applyFilter = !(path[3].equals("review");
, because I think we don't want to use ETags when a review is added or deleted.
rebase branch "updateReview" onto branch "master"
* Access token dialog improvements * Set focus on the Copy button --------- Co-authored-by: amvanbaren <[email protected]>
* Search bar improvements * Remove 'Space' key in extension-list-header.tsx Change charCode 13 to key 'Enter' in namespace-input.tsx --------- Co-authored-by: amvanbaren <[email protected]>
Fixes eclipse#427 Change Namespace Evict caches Update search entries
Fixes eclipse#452 Added UpstreamProxyService Add url rewriting to UpstreamVSCodeService.java # Conflicts: # server/src/main/java/org/eclipse/openvsx/UpstreamRegistryService.java # server/src/main/java/org/eclipse/openvsx/adapter/UpstreamVSCodeService.java
Update extension publicId of already published extensions when a new extension has the same publicId
Use react-helmet to make <head> tags configurable through pageSettings for homepage, extension and namespace pages Simplify header tags Pass params instead of only name
bump webui version # Conflicts: # webui/package.json
Add possibility to delay running migrations, so that deployment can finish before migrations run
Added FixTargetPlatformMigration Remove extensionFile at end of a migration Don't run migrations in mirror mode
Improve social links UX
Use timestamp in namespace logo to bust browser cache
Currently copy-pasting some commands with smart quotes results in errors. Replace all the smart quotes with straight quotes for consistency. Signed-off-by: David Xia <[email protected]>
server: move files to new namespace in background job webui: show confirmation dialog, instead of loading new namespace
Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.76.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](webpack/webpack@v5.75.0...v5.76.0) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development ... Signed-off-by: dependabot[bot] <[email protected]>
Merge namespace members Return error if namespaces contain duplicate extensions
668438a
to
082d053
Compare
@yiningwang11 I've opened PR #761. It contains your changes and clears the cache when a review is posted or deleted. |
fixes #613
The review list is not updated because it always gets loaded from the disk cache. Making the 'getReviews' always get data from the registry instead of from the cache fixes this issue.