mirror of
https://github.com/livebook-dev/livebook.git
synced 2024-12-27 01:42:11 +08:00
Add support for getting evaluation file during evaluation (#1362)
This commit is contained in:
parent
16fc23e62c
commit
1e324b4f75
6 changed files with 39 additions and 22 deletions
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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} ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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})
|
||||
|
|
Loading…
Reference in a new issue