Skip to content
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

Revise Git watchers #6352

Merged
merged 1 commit into from
Oct 10, 2019
Merged

Revise Git watchers #6352

merged 1 commit into from
Oct 10, 2019

Conversation

AlexTugarev
Copy link
Contributor

@AlexTugarev AlexTugarev commented Oct 9, 2019

What it does

Current Git watchers have several problems:

  • sync calls for not-watching watchers leave them in watching state
  • git status runs may supersede each other
  • singleton repository manager depending on connection scoped git

Fixes #4436

How to test

  • there's some debug logging added in a separate commit to this PR, it helps to see what's going on behind the scene.
  • test cases:
    1. open a workspace with two git repositories
      • see only one watcher is running; try switch to second repo
    2. open a second frontend and make sure to have the same git repo selected as in first one
      • see only one watcher is running
      • switch to the other git repo in both; see only one watcher is running
      • have different repos selected; see two watchers are running

Review checklist

Reminder for reviewers

@westbury
Copy link
Contributor

westbury commented Oct 9, 2019

We have tested the commits here with Mbed Studio and it works as intended. However this breaks our application because the user no longer sees SCM decorators for any changes the user may have made outside the selected Source Control Provider.

We have been releasing Mbed Studio with #3971 cherry-picked into the release branch. This has solved this issue very well for our particular case. I was unaware of issue #4436 and I had thought this was a performance problem that was specific to us, so the issue had not been a priority for me.

We would like to see a solution that maintains the decorators on all projects. The showing of aggregated SCM decorators on parent folders has little value if the users can't see the current status of all folders/projects. I do believe there are solutions that can satisfy all situations and keep all the decorators.

@AlexTugarev
Copy link
Contributor Author

However this breaks our application because the user no longer sees SCM decorators for any changes the user may have made outside the selected Source Control Provider

@westbury if it's part of your application to watch for changes of all repositories, please add this functionality to your application.

from what I learned is, that it was never intended to watch for all repositories for changes. the bug was a combination of issues and the effect was everything but not consistent, i.e. you might have seen changes from a second, but not from a third repo in your workspace.

@AlexTugarev AlexTugarev marked this pull request as ready for review October 9, 2019 13:36
@@ -769,20 +769,20 @@ describe('log', function (): void {

// See https://github.com/eclipse-theia/theia/issues/2143
it('should not fail when executed from the repository root', async () => {
const git = await createGit();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

otherwise git is not found

bindBackendService(GitPath, Git);
// DugiteGit is bound in singleton scope; each connection should use a proxy for that.
const GitProxy = Symbol('GitProxy');
bind(GitProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(DugiteGit), {}));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

any disadvantages doing it like this?

bind(DugiteGit).toSelf().inSingletonScope();
bind(Git).toService(DugiteGit);
bind(DefaultGitInit).toSelf();
bind(GitInit).toService(DefaultGitInit);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I still don't get why this is actually working :-(
I'd expected this to fail as DefaultGitInit depends on MessageService bound in connection scope.
any idea why?
@kittaakos, this used to fail, no?

const reference = await this.getWatcher(repository);
const watcher = reference.object;
reference.dispose();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

in case the watcher was created here to sync after a git operation before a client called in to watch this repo, it happened to be start a zombie watcher not longer managed here.

@AlexTugarev
Copy link
Contributor Author

@westbury, I double-checked with current master and I cannot follow your comment. switching between repositories causes updates of the tree decorates. this PR doesn't change anything there.

2019-10-09 16 20 46

@westbury
Copy link
Contributor

westbury commented Oct 9, 2019

switching between repositories causes updates of the tree decorates. this PR doesn't change anything there.

You are correct, my mistake. I am so used to having our patch in our application that I was not aware that that was the default behavior. I checked back to 11ce1e7 (the oldest commit I could test without installing node 8) and that also only showed decorators on the selected project.

if it's part of your application to watch for changes of all repositories, please add this functionality to your application

Yes, that is what we do but I backed it out for the purpose of testing this PR as I was unaware of the intended default behavior so misunderstood the intent of this PR. Thank you for clarifying.

@AlexTugarev
Copy link
Contributor Author

@svenefftinge please have a look again, I replaced the stm with a loop, it shaves off ~40loc, keeping the rest intact.

Copy link
Contributor

@svenefftinge svenefftinge left a comment

Choose a reason for hiding this comment

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

LGTM, thank you!

- trying to guarantee watcher do not leak
  - `sync` called in `GitRepositoryManager.run` in not-watching state must not leave it watching when done
  - watcher created per repository should not depend on something bound in connection scope
- `Git` should be bound as singleton
  - connection scoped git access should be a proxy for the singleton git
- `git status` calls for same repository should not supersede each other
- `sync` requests should not pile up when a watcher is busy

ref #4436

Signed-off-by: Alex Tugarev <alex.tugarev@typefox.io>
Copy link
Contributor

@kittaakos kittaakos 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 verified the followings on macOS with the electron example:

test cases:

  1. open a workspace with two git repositories
    • see only one watcher is running; try switch to second repo
  2. open a second frontend and make sure to have the same git repo selected as in first one
    • see only one watcher is running
    • switch to the other git repo in both; see only one watcher is running
    • have different repos selected; see two watchers are running

Please update the changelog with the API changes. Thank you!

@AlexTugarev
Copy link
Contributor Author

Thanks for reviewing! I'm removing the debug logging commit & waiting for the build & mergin then.

@akosyakov akosyakov added the git issues related to git label Oct 10, 2019
@AlexTugarev AlexTugarev merged commit 3b34e86 into master Oct 10, 2019
@vince-fugnitto vince-fugnitto deleted the at/fix-git-watcher branch September 29, 2022 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
git issues related to git
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[git] High CPU load with lots of changes and multiple clients
5 participants