Add support for getting evaluation file during evaluation (#1362)

This commit is contained in:
Jonatan Kłosko 2022-08-28 09:28:19 +02:00 committed by GitHub
parent 16fc23e62c
commit 1e324b4f75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 22 deletions

View file

@ -35,7 +35,7 @@ export function initializeIframeSource(iframe, iframePort, iframeUrl) {
iframe.sandbox =
"allow-scripts allow-same-origin allow-downloads allow-modals allow-popups";
iframe.allow =
"accelerometer; ambient-light-sensor; camera; display-capture; encrypted-media; geolocation; gyroscope; microphone; midi; usb; xr-spatial-tracking";
"accelerometer; ambient-light-sensor; camera; display-capture; encrypted-media; geolocation; gyroscope; microphone; midi; usb; xr-spatial-tracking; clipboard-read; clipboard-write";
iframe.src = url;
});
}

View file

@ -308,8 +308,6 @@ defmodule Livebook.Runtime.Evaluator do
end
defp handle_cast({:evaluate_code, code, ref, base_ref, opts}, state) do
Evaluator.IOProxy.configure(state.io_proxy, ref)
Evaluator.ObjectTracker.remove_reference(state.object_tracker, {self(), ref})
context = get_context(state, base_ref)
@ -317,6 +315,8 @@ defmodule Livebook.Runtime.Evaluator do
context = put_in(context.env.file, file)
start_time = System.monotonic_time()
Evaluator.IOProxy.configure(state.io_proxy, ref, file)
{result_context, result, code_error} =
case eval(code, context.binding, context.env) do
{:ok, value, binding, env} ->

View file

@ -23,7 +23,9 @@ defmodule Livebook.Runtime.Evaluator.IOProxy do
@doc """
Starts an IO device process.
Make sure to use `configure/3` to correctly proxy the requests.
For all supported requests a message is sent to the configured
`:send_to` process, so this device serves as a proxy. Make sure
to also call configure/3` before every evaluation.
"""
@spec start_link(pid(), pid(), pid(), pid()) :: GenServer.on_start()
def start_link(evaluator, send_to, runtime_broadcast_to, object_tracker) do
@ -31,16 +33,13 @@ defmodule Livebook.Runtime.Evaluator.IOProxy do
end
@doc """
Sets IO proxy destination and the reference to be attached to all
messages.
Configures IO proxy for a new evaluation.
For all supported requests a message is sent to the configured
`:send_to` process, so this device serves as a proxy. The given
evaluation reference is also included in all messages.
The given reference is attached to all the proxied messages.
"""
@spec configure(pid(), Evaluator.ref()) :: :ok
def configure(pid, ref) do
GenServer.cast(pid, {:configure, ref})
@spec configure(pid(), Evaluator.ref(), String.t()) :: :ok
def configure(pid, ref, file) do
GenServer.cast(pid, {:configure, ref, file})
end
@doc """
@ -75,6 +74,7 @@ defmodule Livebook.Runtime.Evaluator.IOProxy do
%{
encoding: :unicode,
ref: nil,
file: nil,
buffer: [],
input_cache: %{},
token_count: 0,
@ -86,8 +86,8 @@ defmodule Livebook.Runtime.Evaluator.IOProxy do
end
@impl true
def handle_cast({:configure, ref}, state) do
{:noreply, %{state | ref: ref, token_count: 0}}
def handle_cast({:configure, ref, file}, state) do
{:noreply, %{state | ref: ref, file: file, token_count: 0}}
end
def handle_cast(:clear_input_cache, state) do
@ -230,6 +230,10 @@ defmodule Livebook.Runtime.Evaluator.IOProxy do
{{:ok, state.runtime_broadcast_to}, state}
end
defp io_request(:livebook_get_evaluation_file, state) do
{state.file, state}
end
defp io_request(_, state) do
{{:error, :request}, state}
end

View file

@ -1485,7 +1485,7 @@ defmodule Livebook.Session do
file -> file.path
end
file = path <> "#cell"
file = path <> "#cell:#{cell.id}"
smart_cell_ref =
case cell do

View file

@ -34,6 +34,8 @@ defmodule LivebookWeb.Output do
defp border?({:stdout, _text}), do: true
defp border?({:text, _text}), do: true
defp border?({:error, _message}), do: true
# TODO fix spacing and make it an option
defp border?({:grid, _, _}), do: true
defp border?(_output), do: false
defp wrapper?({:frame, _outputs, _info}), do: true

View file

@ -11,7 +11,7 @@ defmodule Livebook.Runtime.Evaluator.IOProxyTest do
start_supervised({Evaluator, [send_to: self(), object_tracker: object_tracker]})
io = Process.info(evaluator.pid)[:group_leader]
IOProxy.configure(io, :ref)
IOProxy.configure(io, :ref, "cell")
%{io: io}
end
@ -67,7 +67,7 @@ defmodule Livebook.Runtime.Evaluator.IOProxyTest do
test "clear_input_cache/1 clears all cached input information", %{io: io} do
pid =
spawn_link(fn ->
IOProxy.configure(io, :ref)
IOProxy.configure(io, :ref, "cell")
assert livebook_get_input_value(io, "input1") == {:ok, :value1}
IOProxy.clear_input_cache(io)
assert livebook_get_input_value(io, "input1") == {:ok, :value2}
@ -106,25 +106,25 @@ defmodule Livebook.Runtime.Evaluator.IOProxyTest do
describe "token requests" do
test "returns different tokens for subsequent calls", %{io: io} do
IOProxy.configure(io, :ref1)
IOProxy.configure(io, :ref1, "cell1")
token1 = livebook_generate_token(io)
token2 = livebook_generate_token(io)
assert token1 != token2
end
test "returns different tokens for different refs", %{io: io} do
IOProxy.configure(io, :ref1)
IOProxy.configure(io, :ref1, "cell1")
token1 = livebook_generate_token(io)
IOProxy.configure(io, :ref2)
IOProxy.configure(io, :ref2, "cell2")
token2 = livebook_generate_token(io)
assert token1 != token2
end
test "returns same tokens for the same ref", %{io: io} do
IOProxy.configure(io, :ref)
IOProxy.configure(io, :ref, "cell")
token1 = livebook_generate_token(io)
token2 = livebook_generate_token(io)
IOProxy.configure(io, :ref)
IOProxy.configure(io, :ref, "cell")
token3 = livebook_generate_token(io)
token4 = livebook_generate_token(io)
assert token1 == token3
@ -132,6 +132,13 @@ defmodule Livebook.Runtime.Evaluator.IOProxyTest do
end
end
describe "evaluation file requests" do
test "returns the configured file", %{io: io} do
IOProxy.configure(io, :ref1, "cell1")
assert livebook_get_evaluation_file(io) == "cell1"
end
end
# Helpers
defp reply_to_input_request(_ref, _input_id, _reply, 0), do: :ok
@ -156,6 +163,10 @@ defmodule Livebook.Runtime.Evaluator.IOProxyTest do
io_request(io, :livebook_generate_token)
end
defp livebook_get_evaluation_file(io) do
io_request(io, :livebook_get_evaluation_file)
end
defp io_request(io, request) do
ref = make_ref()
send(io, {:io_request, self(), ref, request})