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

Move UI Comm sender ownership to RMain #583

Merged
merged 5 commits into from
Oct 15, 2024
Merged

Conversation

DavisVaughan
Copy link
Contributor

@DavisVaughan DavisVaughan commented Oct 12, 2024

No description provided.

Comment on lines -897 to +913
let event = UiFrontendEvent::PromptState(PromptStateParams {
input_prompt: info.input_prompt.clone(),
continuation_prompt: info.continuation_prompt.clone(),
// Perform a refresh of the frontend state
// (Prompts, working directory, etc)
self.with_mut_ui_comm_tx(|ui_comm_tx| {
let input_prompt = info.input_prompt.clone();
let continuation_prompt = info.continuation_prompt.clone();

ui_comm_tx.send_refresh(input_prompt, continuation_prompt);
});
{
let kernel = self.kernel.lock().unwrap();
kernel.send_ui_event(event);
}

// Check for pending graphics updates
// (Important that this occurs while in the "busy" state of this ExecuteRequest
// so that the `parent` message is set correctly in any Jupyter messages)
unsafe {
graphics_device::on_did_execute_request(
self.comm_manager_tx.clone(),
self.iopub_tx.clone(),
self.is_ui_comm_connected() && self.session_mode == SessionMode::Console,
)
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously we did a "prompt" refresh here right before unblocking shell, but over on shell when we got unblocked we then did a working directory refresh and a graphics device refresh.

We now do all 3 of those here, which seems way more appropriate

Comment on lines 1201 to 1219
pub fn get_ui_comm_tx(&self) -> Option<&UiCommSender> {
self.ui_comm_tx.as_ref()
}

fn get_mut_ui_comm_tx(&mut self) -> Option<&mut UiCommSender> {
self.ui_comm_tx.as_mut()
}

fn with_ui_comm_tx<F>(&self, f: F)
where
F: FnOnce(&UiCommSender),
{
match self.get_ui_comm_tx() {
Some(ui_comm_tx) => f(ui_comm_tx),
None => {
// Trace level logging, its typically not a bug if the frontend
// isn't connected. Happens in all Jupyter use cases.
log::trace!("UI comm isn't connected.");
},
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea is that in interface.rs we use with_ui_comm_tx() quite a bit because it doesn't log an error if the UI comm isn't connected - which is correct, because this code runs when in Jupyter mode too.

But in specific UI methods in other files (which only run in Positron mode), we use get_ui_comm_tx() which allows us to promote a None sender into an error, because that would be very unexpected

Comment on lines 1760 to +1763
pub fn call_frontend_method(&self, request: UiFrontendRequest) -> anyhow::Result<RObject> {
log::trace!("Calling frontend method '{request:?}'");
log::trace!("Calling frontend method {request:?}");

let ui_comm_tx = self.get_ui_comm_tx().ok_or_else(|| {
anyhow::anyhow!("UI comm is not connected. Can't execute request {request:?}")
})?;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should only be called when we are in Positron mode, so this feels like an error

Comment on lines 1722 to 1793
anyhow::bail!("Can't deserialize RPC response for {request:?}:\n{err:?}");
return Err(anyhow::anyhow!(
"Can't deserialize RPC response for {request:?}:\n{err:?}"
));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixing up a few bail!s

Comment on lines 203 to 223
ExecuteResponse::ReplyException(err) => Err(err),
};

let mut kernel = self.kernel.lock().unwrap();
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 really really like that we now just:

  • send request
  • get response
  • return response

With no extra funny business

Comment on lines 28 to 32
let main = RMain::get();
let event = UiFrontendEvent::ShowMessage(params);
main.send_frontend_event(event);

let main = RMain::get();
let ui_comm_tx = main.get_ui_comm_tx().ok_or_else(ui_comm_not_connected)?;
ui_comm_tx.send_event(event);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously would eventually just do

log::info!("Discarding message {msg:?}; no frontend UI comm connected");

but i think we should actually error here

Comment on lines +61 to +67
pub fn send_refresh(&mut self, input_prompt: String, continuation_prompt: String) {
self.refresh_prompt_info(input_prompt, continuation_prompt);

if let Err(err) = self.refresh_working_directory() {
log::error!("Can't refresh working directory: {err:?}");
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All UI related refreshes should be here now - like an LSP refresh

@DavisVaughan DavisVaughan changed the title Move UI Comm ownership to RMain Move UI Comm sender ownership to RMain Oct 13, 2024
@DavisVaughan DavisVaughan marked this pull request as ready for review October 13, 2024 18:19
@DavisVaughan DavisVaughan requested a review from lionel- October 13, 2024 18:19
@DavisVaughan DavisVaughan force-pushed the feature/rmain-owns-kernel branch from 3c3b08c to 4f0fc93 Compare October 13, 2024 19:34
Copy link
Contributor

@lionel- lionel- left a comment

Choose a reason for hiding this comment

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

Nice progress! With a bit more effort I think we could get in an even better place with all UI-related stuff living in the UI comm module.

@@ -48,12 +48,20 @@ unsafe fn ps_browse_url_impl(url: SEXP) -> anyhow::Result<SEXP> {
log::trace!("Help is not handling URL");
}

// TODO: What is the right thing to do outside of Positron when
// `options(browser =)` is called? Right now we error.
Copy link
Contributor

Choose a reason for hiding this comment

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

The right thing to do outside Positron is to use the default action, i.e. open in a web browser. So we should not set up that option unless Positron is connected.

Ideally Positron would inject the option via its init file. Or the UI comm could launch an idle task to do it, but there would a short time where the option is not set with this approach.

crates/ark/src/interface.rs Show resolved Hide resolved
crates/ark/src/interface.rs Show resolved Hide resolved
crates/ark/src/interface.rs Outdated Show resolved Hide resolved
crates/ark/src/interface.rs Show resolved Hide resolved
@@ -1683,26 +1756,26 @@ impl RMain {
}

pub fn call_frontend_method(&self, request: UiFrontendRequest) -> anyhow::Result<RObject> {
log::trace!("Calling frontend method '{request:?}'");
log::trace!("Calling frontend method {request:?}");

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we'd move that method to another global singleton created by the UI comm.
Which would be nice because it's a bit untidy for the R-level methods to have full access to RMain.

crates/ark/src/ui/events.rs Outdated Show resolved Hide resolved
crates/ark/src/interface.rs Show resolved Hide resolved
crates/ark/src/shell.rs Show resolved Hide resolved
@DavisVaughan DavisVaughan merged commit 67ff702 into main Oct 15, 2024
6 checks passed
@DavisVaughan DavisVaughan deleted the feature/rmain-owns-kernel branch October 15, 2024 17:35
@github-actions github-actions bot locked and limited conversation to collaborators Oct 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants