Skip to content

[#412] cache enablement for URI #415

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

Merged
merged 29 commits into from
Feb 11, 2025

Conversation

ghentschke
Copy link
Contributor

@ghentschke ghentschke commented Feb 5, 2025

part of #412
fixes #231

Copy link
Member

@ruspl-afed ruspl-afed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
So, only restart will clear the cache and this is desired, correct?

@ghentschke
Copy link
Contributor Author

LGTM So, only restart will clear the cache and this is desired, correct?

Yes. But I would like to add a clear mechanism which would be triggered when the preferLspEditor has been modifed. I'll wait until your PR #410 has been merged.

@ruspl-afed
Copy link
Member

I'll wait until your PR #410 has been merged.

Please fill free to merge both when needed.

Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that the PropertyTester's test method is called a lot so speeding that up has great value. Here are some comments.

  • The title of this PR and commit need cash -> cache
  • PropertyTester must be stateless, see javadoc - the new cache is kindof stateful, or rather you may end up with multiple caches the way it is done now.
  • The cache is accessed from multiple threads, so some consideration to concurrency is needed.
  • Should this be doing LRU style so that items don't stay and this grows forever. CDT has one org.eclipse.cdt.internal.core.LRUCache<K, V>
  • I think the discussions in [#1207] cache IResource in EnablementTester eclipse-lsp4e/lsp4e#1208 are relevant to this PR too so I am cross referencing them here
  • Cache invalidation may be needed, see longer comment below

Cache invalidation

My concern with this change is rather a corner case, but that there should be logic to clear the cache as some of the tests can return different results. For example you are checking content types and caching that result. In that case you need to add a listener org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(IContentTypeChangeListener) so that you find out about content type changes.

A simple manual test:

  1. Create a file called "file.jonah"
  2. Double-click to open, will not be opened in CDT LSP because it isn't a C/C++ file
  3. Add jonah as a C file extension in preferences:
    image
  4. Make sure the file now opens as an LSP editor

Doing a addContentTypeChangeListener will be sufficient to invalidate cache for content type changes, similar mechanism may be needed for other cases.

I mentioned LRU above, but time based caching may also be useful.

@ghentschke ghentschke changed the title [#412] cash enablement for URI [#412] cache enablement for URI Feb 5, 2025
@ghentschke
Copy link
Contributor Author

Thank you @jonahgraham for the good input I'll consider it!

@ghentschke
Copy link
Contributor Author

ghentschke commented Feb 6, 2025

Ok, this is more a reminder to me:
The cache shall be cleared if:

  • the Prefer LSP Editor setting has been changed (workspace or project level) or
  • on changes in the c/c++ content types for which we enable LSP4E

A resource shall be removed form the cache if it's getting closed in the editor.

The cache shall be implemented as FIFO buffer with n entries which considers concurrency and stateless aspects

@ghentschke
Copy link
Contributor Author

So, I think this should work now. Please review.

@ghentschke
Copy link
Contributor Author

Note: org.eclipse.cdt.lsp.internal.editor.EditorPreferredOptions.removePreferenceChangedListener(IPreferenceChangeListener) won't be called since the lifetime of the org.eclipse.cdt.lsp.internal.editor.EditorPreferredOptions.EditorPreferredOptions(EditorMetadata, String, IScopeContext[], LanguageServerEnable) instance is not easy to determine.

@ghentschke
Copy link
Contributor Author

Sorry, I think this is it. I found some issue during tests.

Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have only been able to review on my phone. I can try running it up next week.

Optional.ofNullable(LSPEclipseUtils.toUri(editor.getEditorInput())).ifPresent(uri -> {
var data = cache.get(uri);
if (data != null) {
if (--data.counter <= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a small comment that counter field should only be accesed from SWT main thread is appropriate here. AFAICT that is how this is implemented as I assume partOpened and partClosed are only called on SWT main thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the partOpen and partClosed methods are called in the main thread

if (--data.counter <= 0) {
cache.remove(uri);
} else {
cache.put(uri, data);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line seems to be a no-op, just putting back in the same instance as you extracted on line 146

if (data != null) {
data.enable = true;
++data.counter;
cache.put(uri, data);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No-op line?

@jonahgraham
Copy link
Member

This change looks good and I think you have well resolved all my previous issues.

this would lead to descreased performance because the cache is only
filled on file open. All opened files would not be cached if the cache
is getting cleared.
- all opened files in the LSP based editor are added to cache again if
the content is still a C/C++ content.
- clean up API of CLanguageServerEnableCache
Use case: Several C/C++ files are opened in LSP based editor -> restart
-> Change C/C++ content type -> select file -> partOpened gets called
and increases the opened counter ==> Fault: counter will be increased
twice (1st time during restore after content type change, 2nd time on
selection (file was not yet selected after restart)
@ruspl-afed
Copy link
Member

thanks!

because they are distinctable and solves the clear-cache-problem when
the same URI is opened in several windows. Otherwise we do not know if
the URI is still opened somewhere and the cache shouldn't be removed for
this URI.
@ghentschke
Copy link
Contributor Author

I don't know. The unit tests run on my machine successfully but not on the server:
at org.eclipse.cdt.lsp.test.internal.server.CLanguageServerEnableCacheTest.testCacheRemovedAfterFileGetsClosed(CLanguageServerEnableCacheTest.java:76)

@jonahgraham
Copy link
Member

@ghentschke If I run CLanguageServerEnableCacheTest in my IDE with default plug-ins enabled it passes, but if I try to simulate what Tycho does and only enable the plug-ins in the dependency tree it fails locally for me like it does on the build machine.

See https://github.com/eclipse-cdt/cdt/blob/main/TESTING.md#using-limited-sets-of-plug-ins-in-tests for some guidance on how to setup the test in the IDE. Specifically for this case I did this:

  1. Right-click on CLanguageServerEnableCacheTest -> Run As -> JUnit Plugin Test
  2. The tests pass
  3. Open launch configuration dialog, select plug-ins tab
  4. Change "Launch with" to Plug-ins selected below
  5. Press Deselect All
  6. Check "org.eclipse.cdt.lsp.test"
  7. Click Select Required, I end up with about 212 selected bundles
  8. Run this launch
  9. Tests seem to fail in the same way as on build machine

For 7 above here is a screenshot with "Only show selected" checked

image

NOTE: CDT mostly avoids using fragments for tests. One of the advantages of this is that the test bundles are full-fledged bundles. The flow in the CDT instructions (highlight link) don't work for CDT LSP because CDT LSP uses a fragment and can't be selected. This is why I gave explicit instructions above.


So what to do about the difference. There is probably some implicit dependency the test has for correct behavior. If so, you need to tell tycho about it or remove that dependency. Here is an example in CDT.

@jonahgraham
Copy link
Member

NOTE: CDT mostly avoids using fragments for tests. One of the advantages of this is that the test bundles are full-fledged bundles. The flow in the CDT instructions (highlight link) don't work for CDT LSP because CDT LSP uses a fragment and can't be selected. This is why I gave explicit instructions above.

I raised eclipse-pde/eclipse.pde#1607 to add the ability to PDE to create the kind of launch that can include the fragment.

@ghentschke
Copy link
Contributor Author

@jonahgraham Thanks for the hints!!! Now it works.

Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghentschke I hope my comment here makes sense - the combination of adapter factories, handling and auto-downloading of URIs and EGit registering something globally (that arguably it shouldn't) makes this a bit of a mess.

Comment on lines 9 to 10
org.eclipse.egit.ui,
org.eclipse.egit.core
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comment - please remove this dependency

ghentschke and others added 2 commits February 11, 2025 07:14
@ghentschke
Copy link
Contributor Author

@jonahgraham any objections left?

@ghentschke ghentschke merged commit a2f4434 into eclipse-cdt:main Feb 11, 2025
3 checks passed
@ghentschke
Copy link
Contributor Author

Thank you @jonahgraham and @ruspl-afed !

@ghentschke ghentschke deleted the cash-enablement branch February 12, 2025 06:15
@jonahgraham jonahgraham added this to the 3.0.0 milestone Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Start LS when a C/C++ file is opened with the LSP based editor
3 participants