这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 12 additions & 32 deletions Microsoft.DotNet.Try.Client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions Microsoft.DotNet.Try.Jupyter.Tests/ExecuteRequestHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public async Task handles_executeRequest()
}

[Fact]
public async Task sends_executeReply_message_on_codeSubmissionEvaluated()
public async Task sends_ExecuteReply_message_on_codeSubmissionEvaluated()
{
var kernel = new CSharpRepl();

Expand Down Expand Up @@ -83,7 +83,7 @@ public async Task sends_executeReply_with_error_message_on_codeSubmissionEvaluat
}

[Fact]
public async Task sends_executeResult_message_on_valueProduced()
public async Task sends_ExecuteReply_message_on_ValueProduced()
{
var kernel = new CSharpRepl();

Expand All @@ -99,5 +99,22 @@ public async Task sends_executeResult_message_on_valueProduced()
.Should().Contain(message =>
message.Contains(MessageTypeValues.ExecuteResult));
}

[Fact]
public async Task sends_ExecuteReply_message_when_submission_contains_only_a_directive()
{
var kernel = new CompositeKernel
{
new CSharpRepl()
};

var handler = new ExecuteRequestHandler(kernel);
var request = Message.Create(new ExecuteRequest("#kernel csharp"), null);
await handler.Handle(new JupyterRequestContext(_serverChannel, _ioPubChannel, request, _kernelStatus));

_serverRecordingSocket.DecodedMessages
.Should().Contain(message =>
message.Contains(MessageTypeValues.ExecuteReply));
}
}
}
27 changes: 12 additions & 15 deletions Microsoft.DotNet.Try.Jupyter/ExecuteRequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ public class ExecuteRequestHandler : IDisposable
{
private readonly IKernel _kernel;
private readonly RenderingEngine _renderingEngine;
private readonly ConcurrentDictionary<Guid, OpenRequest> _openRequests = new ConcurrentDictionary<Guid, OpenRequest>();
private readonly ConcurrentDictionary<IKernelCommand, OpenRequest> _openRequests = new ConcurrentDictionary<IKernelCommand, OpenRequest>();
private int _executionCount;
private readonly CodeSubmissionProcessors _processors;
private readonly CompositeDisposable _disposables = new CompositeDisposable();

private class OpenRequest : IDisposable
Expand All @@ -34,7 +33,6 @@ private class OpenRequest : IDisposable

public OpenRequest(JupyterRequestContext context, ExecuteRequest executeRequest, int executionCount, Guid id, Dictionary<string, object> transient)
{

Context = context;
ExecuteRequest = executeRequest;
ExecutionCount = executionCount;
Expand All @@ -61,7 +59,6 @@ public ExecuteRequestHandler(IKernel kernel)
_renderingEngine.RegisterRenderer(typeof(IDictionary), new DictionaryRenderer());
_renderingEngine.RegisterRenderer(typeof(IList), new ListRenderer());
_renderingEngine.RegisterRenderer(typeof(IEnumerable), new SequenceRenderer());
_processors = new CodeSubmissionProcessors();
}

public async Task Handle(JupyterRequestContext context)
Expand All @@ -73,15 +70,16 @@ public async Task Handle(JupyterRequestContext context)
try
{
var command = new SubmitCode(executeRequest.Code, "csharp");
command = await _processors.ProcessAsync(command);
var id = command.Id;

var id = Guid.NewGuid();

var transient = new Dictionary<string, object> { { "display_id", id.ToString() } };

var openRequest = new OpenRequest(context, executeRequest, executionCount, id, transient);
_openRequests[id] = openRequest;
_openRequests[command] = openRequest;

var kernelResult = await _kernel.SendAsync(command);
openRequest.AddDisposable(kernelResult.Events.Subscribe(OnKernelResultEvent));
openRequest.AddDisposable(kernelResult.KernelEvents.Subscribe(OnKernelResultEvent));
}
catch (Exception e)
{
Expand Down Expand Up @@ -118,7 +116,6 @@ public async Task Handle(JupyterRequestContext context)
context.RequestHandlerStatus.SetAsIdle();
}
}


void OnKernelResultEvent(IKernelEvent value)
{
Expand All @@ -142,9 +139,9 @@ void OnKernelResultEvent(IKernelEvent value)
}
}

private static void OnCodeSubmissionEvaluatedFailed(CodeSubmissionEvaluationFailed codeSubmissionEvaluationFailed, ConcurrentDictionary<Guid, OpenRequest> openRequests)
private static void OnCodeSubmissionEvaluatedFailed(CodeSubmissionEvaluationFailed codeSubmissionEvaluationFailed, ConcurrentDictionary<IKernelCommand, OpenRequest> openRequests)
{
var openRequest = openRequests[codeSubmissionEvaluationFailed.ParentId];
var openRequest = openRequests[codeSubmissionEvaluationFailed.Command];

var errorContent = new Error(
eName: "Unhandled Exception",
Expand Down Expand Up @@ -181,9 +178,9 @@ private static void OnCodeSubmissionEvaluatedFailed(CodeSubmissionEvaluationFail
}

private static void OnValueProduced(ValueProduced valueProduced,
ConcurrentDictionary<Guid, OpenRequest> openRequests, RenderingEngine renderingEngine)
ConcurrentDictionary<IKernelCommand, OpenRequest> openRequests, RenderingEngine renderingEngine)
{
var openRequest = openRequests[valueProduced.ParentId];
var openRequest = openRequests[valueProduced.Command];
try
{
var rendering = renderingEngine.Render(valueProduced.Value);
Expand Down Expand Up @@ -232,9 +229,9 @@ private static void OnValueProduced(ValueProduced valueProduced,
}

private static void OnCodeSubmissionEvaluated(CodeSubmissionEvaluated codeSubmissionEvaluated,
ConcurrentDictionary<Guid, OpenRequest> openRequests)
ConcurrentDictionary<IKernelCommand, OpenRequest> openRequests)
{
var openRequest = openRequests[codeSubmissionEvaluated.ParentId];
var openRequest = openRequests[codeSubmissionEvaluated.Command];
// reply ok
var executeReplyPayload = new ExecuteReplyOk(executionCount: openRequest.ExecutionCount);

Expand Down
3 changes: 1 addition & 2 deletions Microsoft.DotNet.Try.js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 31 additions & 7 deletions WorkspaceServer.Tests/Kernel/CSharpReplTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.IO;
using FluentAssertions;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Recipes;
using WorkspaceServer.Kernel;
using Xunit;

Expand Down Expand Up @@ -55,7 +58,7 @@ public async Task it_returns_exceptions_thrown_in_user_code()
.Should()
.BeOfType<CodeSubmissionEvaluationFailed>()
.Which
.Error
.Exception
.Should()
.BeOfType<NotImplementedException>();
}
Expand Down Expand Up @@ -118,9 +121,6 @@ public async Task it_returns_the_result_of_a_null_expression()

KernelEvents.OfType<ValueProduced>()
.Last()
.Should()
.BeOfType<ValueProduced>()
.Which
.Value
.Should()
.BeNull();
Expand Down Expand Up @@ -149,12 +149,36 @@ public async Task it_aggregates_multiple_submissions()

KernelEvents.OfType<ValueProduced>()
.Last()
.Should()
.BeOfType<ValueProduced>()
.Which
.Value
.Should()
.Be(3);
}

[Fact]
public async Task it_can_load_assembly_references_using_r_directive()
{
var kernel = await CreateKernelAsync();

var dll = new FileInfo(typeof(JsonConvert).Assembly.Location).FullName;

await kernel.SendAsync(
new SubmitCode($"#r \"{dll}\""));
await kernel.SendAsync(
new SubmitCode(@"
using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(new { value = ""hello"" });

json
"));

KernelEvents.Should()
.ContainSingle(e => e is ValueProduced);
KernelEvents.OfType<ValueProduced>()
.Single()
.Value
.Should()
.Be(new { value = "hello" }.ToJson());
}
}
}
Loading