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

refactor(net): removes direct ui invocation from filemgr thread #20480

Merged
merged 11 commits into from Apr 29, 2018

Conversation

@kwonoj
Copy link
Contributor

kwonoj commented Mar 30, 2018

This PR tries to refactor net::filemanager_thread implementation, removes direct ui-related code invocation but ask constellation. I believe overall organization might need to be refactored still as I took my own liberty to wire up dots and dots between components, which could be non-recommended practices.

Probably point of review / need to be updated are

  1. Communication between components
    Currently it's wired as like below:
+----------------+                    +---------------+              +---------+
|                |  constellationMsg  |               | embedderMsg  |         |
| filemgr_thread +------------------->+ constellation +------------->+ browser |
|                |                    |               |              |         |
+-----+----------+                    +---------------+              +----+----+
      ^                                                                   |
      +-------------------------------------------------------------------+
                                filelist: Vec(String)
  • is this feasible approach?
  • does organization of message / fn (where to put consteallation / embedder msg & fns) are legit?
  1. Removal of filemanger_thread::UIProvider
  • As filemanager_thread no longer need to aware actual ui, this PR removes UIProvider completely and let invoke tinyfiledialog directly in message listener. Maybe UIProvider itself still being needed?
  1. Overall fn organization
  • To reduce duplicated code it takes single msg with boolean flag to distinguish selecting multiple files, may feasible / or better to create explicit paths between two.
  1. Invoking tfd in a separate thread
  • This was mainly to align behavior to previous implentation, where tfd was invoked inside of filemanager_thread so does not block main. It may possibly just let block instead.

and of course, a lot of other codes need to follow better practices.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #20428 (github issue number if applicable).
  • There are tests for these changes OR
  • These changes do not require tests because _____
  • Manually verified file picker <input type=files> can pick up files.

This change is Reviewable

@highfive
Copy link

highfive commented Mar 30, 2018

Heads up! This PR modifies the following files:

  • @asajeffrey: components/constellation/constellation.rs
  • @cbrewster: components/constellation/constellation.rs
  • @paulrouget: components/constellation/constellation.rs, components/servo/lib.rs, ports/servo/browser.rs, components/compositing/compositor_thread.rs
  • @fitzgen: components/script_traits/lib.rs
  • @KiChjang: components/net/Cargo.toml, components/net/filemanager_thread.rs, components/net/resource_thread.rs, components/net/lib.rs, components/net/tests/resource_thread.rs and 4 more
@bors-servo
Copy link
Contributor

bors-servo commented Apr 2, 2018

The latest upstream changes (presumably #20391) made this pull request unmergeable. Please resolve the merge conflicts.

@paulrouget
Copy link
Contributor

paulrouget commented Apr 2, 2018

I see you call open_file_dialog from a different thread to not block the main thread. Does that work well on the 3 platforms? (I can try on Windows and Mac if that helps).

@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from b758fd0 to 1d4287c Apr 2, 2018
@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 2, 2018

@paulrouget I just give a quick try (open tfd for single / multiple dialog, check if it unblocks main) on linux / windows / macOS, and all platform seems working as expected. (Does not block / no immediate panic or unexpected behavior).

Copy link
Contributor

paulrouget left a comment

Could we short-circuit the constellation and directly use the embedder channel (EmbedderProxy)?

@@ -141,6 +142,8 @@ pub enum EmbedderMsg {
LoadComplete(TopLevelBrowsingContextId),
/// A pipeline panicked. First string is the reason, second one is the backtrace.
Panic(TopLevelBrowsingContextId, String, Option<String>),
/// Open file dialog to select files

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 3, 2018

Contributor

Can you add a comment about what that boolean is for?

ui: &UI)
where UI: UIProvider,
{
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 3, 2018

Contributor

I don't think we have to make a distinction between the platforms here. Let send a message to the embedder no matter the platform, and let the embedder decide what to do depending on the platform.

@@ -1076,6 +1077,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromCompositorMsg::SetCursor(cursor) => {
self.handle_set_cursor_msg(cursor)
}
FromCompositorMsg::OpenFileSelectDialog(patterns, multiple_files, sender) => {

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 3, 2018

Contributor

Having to use FromCompositorMsg is unfortunate. Maybe a Request::Script might be better? Or even its own type of request.

@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 3, 2018

Could we short-circuit the constellation and directly use the embedder channel (EmbedderProxy)?

@paulrouget I haven't tried but it may possible, mostly I tried follow steps in original issue #20428 's network code should send a message to the constellation, which can talk to the embedder and receive the final selection to return to the network code to let constellation handles it. May I update PR as suggested?

@paulrouget
Copy link
Contributor

paulrouget commented Apr 3, 2018

So far, only the constellation talks to the embedder via EmbedderMsg. So maybe let's keep it the way you did.

@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from 1d4287c to 2c38b48 Apr 3, 2018
@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 3, 2018

@paulrouget appreciate for feedback, I tried to update PR as suggested

  • create FileManagerMsg and let it handled via Script::Request
  • move out platform-aware logic from filethread

If there are things need to be corrected, I'll update per suggestions.

@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch 2 times, most recently from c45873d to 61a2b73 Apr 4, 2018
@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from 61a2b73 to 3b2a71c Apr 9, 2018
@paulrouget
Copy link
Contributor

paulrouget commented Apr 10, 2018

Sorry. Was away for a while. I'll look at this again soon.

@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 10, 2018

no worries. 👍

@paulrouget
Copy link
Contributor

paulrouget commented Apr 10, 2018

I had a quick chat with @cbrewster and we agree that it's fine if the script thread has access to the EmbedderProxy. We could short-circuit the constellation.

Copy link
Contributor

paulrouget left a comment

So I'd really like to see how that would work if we were to share the embedder proxy with the script thread. Sorry, changed my mind again :|

@@ -141,6 +142,8 @@ pub enum EmbedderMsg {
LoadComplete(TopLevelBrowsingContextId),
/// A pipeline panicked. First string is the reason, second one is the backtrace.
Panic(TopLevelBrowsingContextId, String, Option<String>),
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
GetSelectedFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 10, 2018

Contributor

Maybe rename that to PickFiles, RequestFiles or SelectFiles?

self.embedder_proxy.send(msg);
}
}
}

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 10, 2018

Contributor

If we are forwarding a message, maybe we want to keep the same name.

Also, I talked to @cbrewster and we agree that maybe it's better to give access to the EmbedderProxy to each script thread.

fn platform_get_selected_files(_patterns: Vec<FilterPattern>,
_multiple_files: bool,
sender: IpcSender<Option<Vec<String>>>) {
sender.send(None);

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 10, 2018

Contributor

Maybe warn!("File picker not implemented") first?

@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 10, 2018

I'll try to update short-curcuit as suggested. Due to personal schedules I may need some time to wrap things up, once done will ping via @-mention here.

@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch 3 times, most recently from fcb7bcc to c9b656f Apr 11, 2018
@kwonoj
Copy link
Contributor Author

kwonoj commented Apr 14, 2018

@paulrouget Updated PR as suggested,

  • now filemanager_thread access to embedderProxy directly
  • refactored EmbedderMsg name as suggested.
@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from c9b656f to 62dd3dc Apr 14, 2018
Copy link
Contributor

paulrouget left a comment

This feels a lot better! I think we made the right decision to use the embedder proxy.

A few neats and then I think we good to go.

Thank you.

@@ -546,7 +546,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
STF: ScriptThreadFactory<Message=Message>
{
/// Create a new constellation thread.
pub fn start(state: InitialConstellationState) -> (Sender<FromCompositorMsg>, IpcSender<SWManagerMsg>) {
pub fn start(state: InitialConstellationState)
-> (Sender<FromCompositorMsg>, IpcSender<SWManagerMsg>) {

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Unnecessary change.

thread::Builder::new().name("select files".to_owned()).spawn(move || {
store.select_files(filter, sender, origin, opt_test_paths, ui);
store.select_files(filter, sender, origin, opt_test_paths, embedder );

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Neat: Trailing space.

embedder_proxy: EmbedderProxy) -> Option<Vec<String>> {
if opts::get().headless {
return None;
}

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Can you let the embedder take the decision to return None when we run in headless mode?

This comment has been minimized.

Copy link
@kwonoj

kwonoj Apr 16, 2018

Author Contributor

Guess so, will try for it.

ui: &UI)
where UI: UIProvider,
{
fn get_selected_files(&self,

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Neat: Maybe rename get_selected_files to query_files_from_embedder.

[[test]]
name = "main"
path = "tests/main.rs"

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Neat: extra line.

@@ -118,7 +118,8 @@ fn test_fetch_blob() {
use ipc_channel::ipc;
use net_traits::blob_url_store::BlobBuf;

let context = new_fetch_context(None);
//let (sender, _receiver) = ipc::channel().unwrap();

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Remove this comment.

#[test]
fn test_filemanager() {
let filemanager = FileManager::new();
let filemanager = FileManager::new(create_embedder_proxy());
PREFS.set("dom.testing.htmlinputelement.select_files.enabled", PrefValue::Boolean(true));

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

I'm wondering why this was not necessary before?

This comment has been minimized.

Copy link
@kwonoj

kwonoj Apr 16, 2018

Author Contributor

Previously there was mock UI provider in filemanager thread does inject test files instead (https://github.com/servo/servo/pull/20480/files#diff-5a65a0caa6da8aa6e23da0a4101c6a86L19) regardless of testing prefs. Now changed code path removes UI provider from thread and always asks to embedder message, so setting up test to mock fixture for file selection.

pub enum FileManagerMsg {
/// Requesting to open file select dialog
OpenFileSelectDialog(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>)
}

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

I might have missed something, but is that message actually used somewhere?

This comment has been minimized.

Copy link
@kwonoj

kwonoj Apr 16, 2018

Author Contributor

No, I guess it's my mistake leftover while refactoring. Thanks for catching.

let msg = EmbedderMsg::SelectFiles(patterns, multiple_files, ipc_sender);

embedder_proxy.send(msg);
ipc_receiver.recv().unwrap()

This comment has been minimized.

Copy link
@paulrouget

paulrouget Apr 16, 2018

Contributor

Catch the error here:

match ipc_receiver.recv() {
    Err(e) => warn!("Failed to receive files from emebdder ({}).", e),
    ...
}
@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from 62dd3dc to 2db008e Apr 16, 2018
@bors-servo
Copy link
Contributor

bors-servo commented Apr 27, 2018

The latest upstream changes (presumably #20533) made this pull request unmergeable. Please resolve the merge conflicts.

kwonoj added 11 commits Mar 30, 2018
@kwonoj kwonoj force-pushed the kwonoj:refactor-file-manager branch from e98c4ff to d94def6 Apr 27, 2018
@KiChjang
Copy link
Member

KiChjang commented Apr 29, 2018

@bors-servo r=paulrouget

@bors-servo
Copy link
Contributor

bors-servo commented Apr 29, 2018

📌 Commit d94def6 has been approved by paulrouget

@bors-servo
Copy link
Contributor

bors-servo commented Apr 29, 2018

Testing commit d94def6 with merge bf66767...

bors-servo added a commit that referenced this pull request Apr 29, 2018
refactor(net): removes direct ui invocation from filemgr thread

<!-- Please describe your changes on the following line: -->
- relates to #20428.

This PR tries to refactor `net::filemanager_thread` implementation, removes direct ui-related code invocation but ask constellation. I believe overall organization might need to be refactored still as I took my own liberty to wire up dots and dots between components, which could be non-recommended practices.

Probably point of review / need to be updated are

1. Communication between components
Currently it's wired as like below:
```
+----------------+                    +---------------+              +---------+
|                |  constellationMsg  |               | embedderMsg  |         |
| filemgr_thread +------------------->+ constellation +------------->+ browser |
|                |                    |               |              |         |
+-----+----------+                    +---------------+              +----+----+
      ^                                                                   |
      +-------------------------------------------------------------------+
                                filelist: Vec(String)
```
- is this feasible approach?
- does organization of message / fn (where to put consteallation / embedder msg & fns) are legit?

2. Removal of `filemanger_thread::UIProvider`
- As filemanager_thread no longer need to aware actual ui, this PR removes `UIProvider` completely and let invoke tinyfiledialog directly in message listener. Maybe UIProvider itself still being needed?

3. Overall fn organization
- To reduce duplicated code it takes single msg with boolean flag to distinguish selecting multiple files, may feasible / or better to create explicit paths between two.

4. Invoking tfd in a separate thread
- This was mainly to align behavior to previous implentation, where tfd was invoked inside of filemanager_thread so does not block main. It may possibly just let block instead.

and of course, a lot of other codes need to follow better practices.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20428 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
- Manually verified file picker `<input type=files>` can pick up files.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20480)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Apr 29, 2018

@bors-servo bors-servo merged commit d94def6 into servo:master Apr 29, 2018
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@kwonoj kwonoj deleted the kwonoj:refactor-file-manager branch Apr 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

7 participants
You can’t perform that action at this time.