in src/Engines/ExecuteRequestHandler.cs [55:159]
protected async virtual Task<ExecutionResult> ExecutionTaskForMessage(Message message, int executionCount, Action onHandled)
{
var engineResponse = ExecutionResult.Aborted;
var code = (message.Content as ExecuteRequestContent)?.Code ?? string.Empty;
this.shellServer.SendIoPubMessage(
new Message
{
ZmqIdentities = message.ZmqIdentities,
ParentHeader = message.Header,
Metadata = null,
Content = new ExecuteInputContent
{
Code = code,
ExecutionCount = executionCount
},
Header = new MessageHeader
{
MessageType = "execute_input"
}
}
);
using (var cancellationTokenSource = new CancellationTokenSource())
{
Action<Message> onInterruptRequest = (message) => cancellationTokenSource.Cancel();
var shellServerSupportsInterrupt = this.shellServer as IShellServerSupportsInterrupt;
if (shellServerSupportsInterrupt != null)
{
shellServerSupportsInterrupt.InterruptRequest += onInterruptRequest;
}
// Make sure that the engine is fully initialized.
await engine.Initialized;
try
{
engineResponse = await engine.Execute(
code,
new BaseEngine.ExecutionChannel(engine, message, router),
cancellationTokenSource.Token
);
}
finally
{
if (shellServerSupportsInterrupt != null)
{
shellServerSupportsInterrupt.InterruptRequest -= onInterruptRequest;
}
}
}
// Send the engine's output as an execution result.
if (engineResponse.Output != null)
{
var serialized = engine.EncodeForDisplay(engineResponse.Output);
this.shellServer.SendIoPubMessage(
new Message
{
ZmqIdentities = message.ZmqIdentities,
ParentHeader = message.Header,
Metadata = null,
Content = new ExecuteResultContent
{
ExecutionCount = executionCount,
Data = serialized.Data,
Metadata = serialized.Metadata
},
Header = new MessageHeader
{
MessageType = "execute_result"
}
}
);
}
// Invoke the onHandled callback prior to sending the execute_reply message.
// This guarantees that the OrderedShellHandler correctly processes the completion
// of this task *before* any processing new task that the client may submit for
// execution immediately upon receiving the execute_reply message.
onHandled();
// Handle the message.
this.shellServer.SendShellMessage(
new Message
{
ZmqIdentities = message.ZmqIdentities,
ParentHeader = message.Header,
Metadata = null,
Content = new ExecuteReplyContent
{
ExecuteStatus = engineResponse.Status,
ExecutionCount = executionCount
},
Header = new MessageHeader
{
MessageType = "execute_reply"
}
}
);
return engineResponse;
}