Create execution context with id (#6947)

`executionContext/create` method has an optional `context_id` parameter. Supplying this argument makes the user's session more reproducible. I.e. this way the language server can recreate the user's session by recording the requests.
This commit is contained in:
Dmitry Bushev 2023-06-06 15:03:04 +01:00 committed by GitHub
parent 86724cb741
commit 76a9a95c5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 25 additions and 14 deletions

View File

@ -118,7 +118,7 @@ trait API {
/// Create a new execution context. Return capabilities executionContext/canModify and
/// executionContext/receivesUpdates containing freshly created ContextId
#[MethodInput=CreateExecutionContextInput, rpc_name="executionContext/create"]
fn create_execution_context(&self) -> response::CreateExecutionContext;
fn create_execution_context(&self, context_id: ContextId) -> response::CreateExecutionContext;
/// Destroy an execution context and free its resources.
#[MethodInput=DestroyExecutionContextInput, rpc_name="executionContext/destroy"]

View File

@ -373,9 +373,9 @@ fn test_execution_context() {
let create_execution_context_response =
response::CreateExecutionContext { context_id, can_modify, receives_updates };
test_request(
|client| client.create_execution_context(),
|client| client.create_execution_context(&context_id),
"executionContext/create",
json!({}),
json!({"contextId":"00000000-0000-0000-0000-000000000000"}),
json!({
"contextId" : "00000000-0000-0000-0000-000000000000",
"canModify" : {

View File

@ -112,7 +112,8 @@ impl Handle {
#[profile(Task)]
pub async fn new(project: model::Project, method: MethodPointer) -> FallibleResult<Self> {
let graph = controller::Graph::new_method(&project, &method).await?;
let execution = project.create_execution_context(method.clone()).await?;
let context_id = Uuid::new_v4();
let execution = project.create_execution_context(method.clone(), context_id).await?;
Ok(Self::new_internal(graph, project, execution))
}

View File

@ -66,10 +66,11 @@ impl ExecutionContext {
pub fn create(
language_server: Rc<language_server::Connection>,
root_definition: language_server::MethodPointer,
id: model::execution_context::Id,
) -> impl Future<Output = FallibleResult<Self>> {
async move {
info!("Creating.");
let id = language_server.client.create_execution_context().await?.context_id;
let id = language_server.client.create_execution_context(&id).await?.context_id;
let model = model::execution_context::Plain::new(root_definition);
info!("Created. Id: {id}.");
let this = Self { id, model, language_server };
@ -419,7 +420,7 @@ pub mod test {
let connection = language_server::Connection::new_mock_rc(ls_client);
let mut test = TestWithLocalPoolExecutor::set_up();
let method = data.main_method_pointer();
let context = ExecutionContext::create(connection, method);
let context = ExecutionContext::create(connection, method, data.context_id);
let context = test.expect_completion(context).unwrap();
Fixture { data, context, test }
}
@ -438,7 +439,7 @@ pub mod test {
fn mock_create_destroy_calls(data: &MockData, ls: &mut language_server::MockClient) {
let id = data.context_id;
let result = Self::expected_creation_response(data);
expect_call!(ls.create_execution_context() => Ok(result));
expect_call!(ls.create_execution_context(id) => Ok(result));
expect_call!(ls.destroy_execution_context(id) => Ok(()));
}

View File

@ -85,6 +85,7 @@ pub trait API: Debug {
fn create_execution_context<'a>(
&'a self,
root_definition: language_server::MethodPointer,
context_id: model::execution_context::Id,
) -> BoxFuture<'a, FallibleResult<model::ExecutionContext>>;
/// Set a new project name.
@ -234,8 +235,10 @@ pub mod test {
let ctx2 = ctx.clone_ref();
project
.expect_create_execution_context()
.withf_st(move |root_definition| root_definition == &ctx.current_method())
.returning_st(move |_root_definition| ready(Ok(ctx2.clone_ref())).boxed_local());
.withf_st(move |root_definition, _context_id| root_definition == &ctx.current_method())
.returning_st(move |_root_definition, _context_id| {
ready(Ok(ctx2.clone_ref())).boxed_local()
});
}
/// Sets up project root id expectation on the mock project, returning a given id.

View File

@ -704,10 +704,12 @@ impl model::project::API for Project {
fn create_execution_context(
&self,
root_definition: MethodPointer,
context_id: execution_context::Id,
) -> BoxFuture<FallibleResult<model::ExecutionContext>> {
async move {
let ls_rpc = self.language_server_rpc.clone_ref();
let context = execution_context::Synchronized::create(ls_rpc, root_definition);
let context =
execution_context::Synchronized::create(ls_rpc, root_definition, context_id);
let context = Rc::new(context.await?);
self.execution_contexts.insert(context.clone_ref());
let context: model::ExecutionContext = context;
@ -928,7 +930,8 @@ mod test {
assert!(result1.is_err());
// Create execution context.
let execution = project.create_execution_context(context_data.main_method_pointer());
let execution = project
.create_execution_context(context_data.main_method_pointer(), context_data.context_id);
let execution = test.expect_completion(execution).unwrap();
// Now context is in registry.

View File

@ -95,7 +95,7 @@ async fn ls_text_protocol_test() {
response.expect("Couldn't write yaml file.");
// Setting execution context.
let execution_context = client.create_execution_context().await;
let execution_context = client.create_execution_context(&Uuid::new_v4()).await;
let execution_context = execution_context.expect("Couldn't create execution context.");
let execution_context_id = execution_context.context_id;
@ -356,7 +356,10 @@ async fn binary_visualization_updates_test_hlp() {
let module_qualified_name = project.qualified_module_name(&module_path);
let module = project.module(module_path).await.unwrap();
info!("Got module: {module:?}");
let graph_executed = controller::ExecutedGraph::new(project, method).await.unwrap();
let context_id = Uuid::new_v4();
let execution_ctx = project.create_execution_context(method.clone(), context_id).await.unwrap();
let graph = controller::Graph::new_method(&project, &method).await.unwrap();
let graph_executed = controller::ExecutedGraph::new_internal(graph, project, execution_ctx);
let the_node = graph_executed.graph().nodes().unwrap()[0].info.clone();
graph_executed.graph().set_expression(the_node.id(), "10+20").unwrap();

View File

@ -53,7 +53,7 @@ async fn getting_component_groups() {
let test = TestOnNewProjectControllersOnly::set_up().await;
let ls_json_connection = test.project.json_rpc();
let main_module = test.project.main_module().to_string();
let execution_ctx = ls_json_connection.create_execution_context().await.unwrap();
let execution_ctx = ls_json_connection.create_execution_context(&Uuid::new_v4()).await.unwrap();
let frame = StackItem::ExplicitCall(ExplicitCall {
method_pointer: MethodPointer {
module: main_module.clone(),