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

Improve ability of downstream apps to control file watching #9163

Merged
merged 1 commit into from
Mar 19, 2021

Conversation

westbury
Copy link
Contributor

@westbury westbury commented Mar 9, 2021

What it does

This PR is a small refactoring that makes it easier for extenders to re-implement a file watching strategy.

As an example of a use-case, we have some very large libraries, pulled into sub-folders in projects as symbolic links. We do not want to listen to the library contents but we do want to know if a symbolic link has been changed to reference a different version of the library. We had code to optimize this, and we want to upgrade to include the file watching changes here: #8546

This involves the following changes:

  1. Extenders may need to override functions in NsfwWatcher, as well as functions in NsfwFileSystemWatcherService. To make it easier to provide an implementation extending NsfwWatcher, I have extracted out createWatcher.
  2. When the watcher is running as a subprocess, we cannot rebind in the process. The best we can do is create a replacement process. To make this easier, I have created a new option entryPoint.
  3. I split the binding of FileSystemWatcherService (when not using a subprocess) into two, first bind the options, then bind the class itself.

It is not impossible for us to make our extensions without these changes. However it does make it easier and it avoids us
needing to duplicate chunks of code.

How to test

The code should work exactly the same as before, so test that file watchers still work correctly.

Review checklist

Reminder for reviewers

@westbury westbury added extensibility issues to simplify ability to extend Theia file-watchers issues related to filesystem watchers - nsfw labels Mar 9, 2021
@westbury westbury requested a review from paul-marechal March 9, 2021 15:09
@westbury westbury force-pushed the watcher-extending branch from aa702f1 to c75740f Compare March 9, 2021 16:29
@westbury westbury force-pushed the watcher-extending branch from c75740f to 0b5e9a8 Compare March 10, 2021 12:42
@westbury
Copy link
Contributor Author

@marechal-p thanks for the review. NsfwFileSystemWatcherServerOptions is definitely a better place than NsfwOptions. The only problem with it is that we are mixing options that are only used single threaded mode together with an option that only applies when using sub-processes, but that's better than mixing with NSFW options. I've made the change.

@paul-marechal
Copy link
Member

paul-marechal commented Mar 10, 2021

@westbury CI is failing: https://github.com/eclipse-theia/theia/pull/9163/checks?check_run_id=2077838349#step:7:242

Sounds like it would be easier to dedicate a binding specifically for this entryPoint value after all.

@westbury westbury force-pushed the watcher-extending branch from 0b5e9a8 to b29bfaa Compare March 10, 2021 22:36
@westbury
Copy link
Contributor Author

@marechal-p yes, I tested my last change only in our application. If I had tested it also in the Electron example then I would have seen the problem. I could have fixed the build break simply by moving the binding of NsfwFileSystemWatcherServerOptions to before the singleThreaded test. However I think you are right that a separate set of options is cleaner. I've pushed a new commit.

@paul-marechal
Copy link
Member

paul-marechal commented Mar 11, 2021

The change looks good to me, I just have one last comment:

I could have fixed the build break simply by moving the binding of NsfwFileSystemWatcherServerOptions to before the singleThreaded test.

Sorry for bothering you again, but I thought about this and my conclusion is that we should avoid conditional bindings. The code before always bound a given symbol, the branching is only meant to target a different implementation.

With your change, some symbols may or may not be bound. We can always do:

if (isBound(identifier)) {
    rebind(identifier)...
}

But I think those symbols should always be bound (NsfwFileSystemWatcherServerOptions and NsfwFileSystemWatcherProcessOptions). If never injected/requested they'll never be resolved.

WDYT?

@westbury westbury force-pushed the watcher-extending branch from b29bfaa to 4f5f145 Compare March 15, 2021 22:00
@westbury
Copy link
Contributor Author

@marechal-p don't worry about bothering me again, we need to get this right as it will be api. I see your point about having some things left unbound depending on the args. We do have different stuff bound depending on, for example, 'backend' vs 'backendElectron' but perhaps that is different.

Putting all the options together in one interface with them all optional seemed a little messy. I therefore put them in a discriminating union. I think that more precisely defines the options. Let me know what you think.

@paul-marechal
Copy link
Member

We do have different stuff bound depending on, for example, 'backend' vs 'backendElectron' but perhaps that is different.

It is different in the way that if someone makes a backendElectron contribution then everything will be available in that context.

I therefore put them in a discriminating union.

So now to rebind it, one has to to a dynamic value to test processType?

rebind(FileWatcherProcessOptions).toDynamicValue(ctx => {
    const options = ctx.container.get(FileWatcherProcessOptions)
    if (options.processType === 'multi') {
        return { ... }
    } else {
        return { ... }
    }
});

My idea was to always bind both option objects, but conditionally use one or the other.

I've pushed a commit on top of your branch with a way I feel would work better? Feel free to either squash it or remove it.

@westbury westbury force-pushed the watcher-extending branch 2 times, most recently from ea30fb7 to 070c546 Compare March 18, 2021 00:06
@westbury
Copy link
Contributor Author

westbury commented Mar 18, 2021

@marechal-p sorry, I totally misunderstood your comment. So basically what we now have is, ignore my last change (back to b29bfaa) and

  1. always bind both options interfaces. I understand your reason for wanting to do that.
  2. extract out createNsfwFileSystemWatcherService and spawnNsfwFileSystemWatcherServiceProcess. Definitely a good idea as this makes the code more readable. Plus makes it easier if someone wants to rebind FileSystemWatcherService but only change one of the two alternatives.
  3. Add the singleThreaded option as a parameter to bindFileSystemWatcherServer. This one I don't really understand. If an extender wants to change this option then surely they would just rebind FileSystemWatcherService. Unbinding everything so they can call bindFileSystemWatcherServer again with different options would be more complicated. However perhaps it is a good pattern that could be useful if other options were added, so this is fine by me.
  4. exporting NSFW_SINGLE_THREADED and NSFW_WATCHER_VERBOSE. Thank you for thinking of this. Now I can replace our copy of this line with an import.

I have re-tested this for both single and multi-threaded. I cannot squash the commits because I can't sign your changes. They need to be merged as two separate commits. I have, however, taken the liberty of changing the message in your commit.

@paul-marechal
Copy link
Member

paul-marechal commented Mar 18, 2021

Regarding 3) I don't understand either. The parameter was already there, I just slightly rewrote its definition... We can forget about this as I don't know what to make of it :)

I cannot squash the commits because I can't sign your changes. They need to be merged as two separate commits.

Do they? You should be able to squash/fixup your commit using git rebase?

Bash:

git rebase -i HEAD~2

Rebase todo-list:

pick <your commit>
fixup <my commit>

Once this is done if you are happy with the changes then I am happy too; I'll approve.

edit: If you worry about IP you could add the following line in your commit after squash:

Co-authored-by: Paul Maréchal <paul.marechal@ericsson.com>

Signed-off-by: Nigel Westbury <nigelipse@miegel.org>
Co-authored-by: Paul Maréchal <paul.marechal@ericsson.com>
@westbury westbury force-pushed the watcher-extending branch from 070c546 to e28183a Compare March 18, 2021 09:03
@westbury
Copy link
Contributor Author

@marechal-p I didn't think I was allowed to squash your commit because of #4279 (comment) . However co-authored seems to be allowed so I have added that and squashed the commits. Also removed the option parameter that is no longer useful.

Thanks for all your time helping with this.

Copy link
Member

@paul-marechal paul-marechal left a comment

Choose a reason for hiding this comment

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

LGTM thanks!

@westbury westbury merged commit 224edb4 into master Mar 19, 2021
@github-actions github-actions bot added this to the 1.12.0 milestone Mar 19, 2021
@vince-fugnitto vince-fugnitto deleted the watcher-extending branch March 19, 2021 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extensibility issues to simplify ability to extend Theia file-watchers issues related to filesystem watchers - nsfw
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants