Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

saving / loading disable status of cells #1209

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0ba0ce7
added helper functions for cell dependencies
lungben Feb 3, 2021
b1702f3
saving / loading disable status of cells
lungben May 31, 2021
8342db6
no separate fields for deativated interactively and on startup
lungben Jun 1, 2021
36007f8
extract disabling of dependent cells to function
lungben Jun 1, 2021
da2d9d4
indirectly disabled cells saved correctly
lungben Jun 1, 2021
c2e0435
do not determine indirectly disabled cells twice
lungben Jun 1, 2021
a94685f
changed symbol for cell deactivation
lungben Jun 2, 2021
471c5ee
disabling delimiter aligned
lungben Jun 6, 2021
604e600
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jun 7, 2021
639457c
consistent line breaks
lungben Jun 7, 2021
2e4ece6
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jun 14, 2021
6cb66c3
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jun 23, 2021
51ef2e2
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jun 24, 2021
0d7d289
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jul 2, 2021
dde3d8e
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jul 7, 2021
afbb92d
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jul 9, 2021
b8240ab
refactor cell disabling
lungben Jul 19, 2021
891b110
add tests that notebook is executable
lungben Jul 19, 2021
8ca9097
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Jul 27, 2021
8421d25
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Aug 6, 2021
67ed2d4
Merge remote-tracking branch 'origin/main' into persistent_cell_deact…
lungben Sep 15, 2021
1b7b214
Merge branch 'master' into persistent_cell_deactivation
lungben Feb 1, 2022
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
33 changes: 24 additions & 9 deletions src/evaluation/Run.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import .ExpressionExplorer: FunctionNameSignaturePair, is_joined_funcname, Using
Base.push!(x::Set{Cell}) = x

"Run given cells and all the cells that depend on them, based on the topology information before and after the changes."
function run_reactive!(session::ServerSession, notebook::Notebook, old_topology::NotebookTopology, new_topology::NotebookTopology, roots::Vector{Cell}; deletion_hook::Function=WorkspaceManager.delete_vars, persist_js_state::Bool=false)::TopologicalOrder
function run_reactive!(session::ServerSession, notebook::Notebook, old_topology::NotebookTopology, new_topology::NotebookTopology, roots::Vector{Cell};
deletion_hook::Function=WorkspaceManager.delete_vars, persist_js_state::Bool=false, indirectly_deactivated::Union{Nothing, Vector{Cell}}=nothing)::TopologicalOrder
# make sure that we're the only `run_reactive!` being executed - like a semaphor
take!(notebook.executetoken)

Expand Down Expand Up @@ -35,13 +36,8 @@ function run_reactive!(session::ServerSession, notebook::Notebook, old_topology:
new_order = topological_order(notebook, new_topology, union(roots, keys(old_order.errable)))
to_run_raw = setdiff(union(new_order.runnable, old_order.runnable), keys(new_order.errable))::Vector{Cell} # TODO: think if old error cell order matters

# find (indirectly) deactivated cells and update their status
deactivated = filter(c -> c.running_disabled, notebook.cells)
indirectly_deactivated = collect(topological_order(notebook, new_topology, deactivated))
for cell in indirectly_deactivated
cell.running = false
cell.queued = false
cell.depends_on_disabled_cells = true
if indirectly_deactivated === nothing
indirectly_deactivated = disable_dependent_cells!(notebook, new_topology)
lungben marked this conversation as resolved.
Show resolved Hide resolved
end

to_run = setdiff(to_run_raw, indirectly_deactivated)
Expand Down Expand Up @@ -108,6 +104,23 @@ function run_reactive!(session::ServerSession, notebook::Notebook, old_topology:
return new_order
end

"""
find (indirectly) deactivated cells and update their status
"""
function disable_dependent_cells!(notebook:: Notebook, topology:: NotebookTopology):: Vector{Cell}
for cell in notebook.cells
cell.depends_on_disabled_cells = false
end
deactivated = filter(c -> c.running_disabled, notebook.cells)
indirectly_deactivated = collect(topological_order(notebook, topology, deactivated))
for cell in indirectly_deactivated
cell.running = false
cell.queued = false
cell.depends_on_disabled_cells = true
end
return indirectly_deactivated
end

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there changes to Run.jl? We already compute the indirectly disabled cells, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to determine the indirectly deactivated cells before saving (in the original implementation it was done afterwards).
In order to avoid double work, run_reactive! gets the list of deactivated cells as (optional) parameter.

See #1209 (comment) and #1209 (comment)

run_reactive_async!(session::ServerSession, notebook::Notebook, to_run::Vector{Cell}; kwargs...) = run_reactive_async!(session, notebook, notebook.topology, notebook.topology, to_run; kwargs...)

function run_reactive_async!(session::ServerSession, notebook::Notebook, old::NotebookTopology, new::NotebookTopology, to_run::Vector{Cell}; run_async::Bool=true, kwargs...)
Expand Down Expand Up @@ -182,6 +195,8 @@ function update_save_run!(session::ServerSession, notebook::Notebook, cells::Arr

update_dependency_cache!(notebook)

indirectly_deactivated = disable_dependent_cells!(notebook, new)

session.options.server.disable_writing_notebook_files || save_notebook(notebook)
lungben marked this conversation as resolved.
Show resolved Hide resolved

# _assume `prerender_text == false` if you want to skip some details_
Expand Down Expand Up @@ -214,7 +229,7 @@ function update_save_run!(session::ServerSession, notebook::Notebook, cells::Arr
sync_nbpkg(session, notebook; save=save)
if !(isempty(to_run_online) && session.options.evaluation.lazy_workspace_creation) && will_run_code(notebook)
# not async because that would be double async
run_reactive_async!(session, notebook, old, new, to_run_online; run_async=false, kwargs...)
run_reactive_async!(session, notebook, old, new, to_run_online; run_async=false, indirectly_deactivated=indirectly_deactivated, kwargs...)
end
end
end
Expand Down
37 changes: 33 additions & 4 deletions src/notebook/Notebook.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ end
const _notebook_header = "### A Pluto.jl notebook ###"
# We use a creative delimiter to avoid accidental use in code
# so don't get inspired to suddenly use these in your code!
const _cell_id_delimiter = "# ╔═╡ "
const _order_delimiter = "# ╠═"
const _order_delimiter_folded = "# ╟─"
const _cell_id_delimiter = "# ╔═╡ "
const _order_delimiter = "# ╠═"
const _order_delimiter_folded = "# ╟─"
const _cell_suffix = "\n\n"

const _running_disabled_prefix = "#=╠═╡ disabled\n"
const _running_disabled_suffix = "\n ╠═╡ disabled =#"
const _depends_on_disabled_cells_prefix = "#=╠═╡ depends on disabled cell(s)\n"
const _depends_on_disabled_cells_suffix = "\n ╠═╡ depends on disabled cell(s) =#"
const _ptoml_cell_id = UUID(1)
const _mtoml_cell_id = UUID(2)

Expand Down Expand Up @@ -121,7 +125,21 @@ function save_notebook(io, notebook::Notebook)
for c in cells_ordered
println(io, _cell_id_delimiter, string(c.cell_id))
# write the cell code and prevent collisions with the cell delimiter
print(io, replace(c.code, _cell_id_delimiter => "# "))

if c.running_disabled
print(io, _running_disabled_prefix)
print(io, replace(c.code, _cell_id_delimiter => "# "))
print(io, _running_disabled_suffix)
elseif c.depends_on_disabled_cells
# if a cell is both disabled directly and indirectly, the first has higher priority
print(io, _depends_on_disabled_cells_prefix)
print(io, replace(c.code, _cell_id_delimiter => "# "))
print(io, _depends_on_disabled_cells_suffix)
else
# cell is not disabled on startup
print(io, replace(c.code, _cell_id_delimiter => "# "))
end

print(io, _cell_suffix)
end

Expand Down Expand Up @@ -211,10 +229,21 @@ function load_notebook_nobackup(io, path)::Notebook
code_raw = String(readuntil(io, _cell_id_delimiter))
# change Windows line endings to Linux
code_normalised = replace(code_raw, "\r\n" => "\n")

# get the information if a cell is disabled
running_disabled = startswith(code_normalised, _running_disabled_prefix)
depends_on_disabled_cells = startswith(code_normalised, _depends_on_disabled_cells_prefix)

# remove the disabled on startup comments for further processing in Julia
code_normalised = replace(replace(code_normalised, _running_disabled_prefix => ""), _running_disabled_suffix => "")
code_normalised = replace(replace(code_normalised, _depends_on_disabled_cells_prefix => ""), _depends_on_disabled_cells_suffix => "")

# remove the cell suffix
code = code_normalised[1:prevind(code_normalised, end, length(_cell_suffix))]

read_cell = Cell(cell_id, code)
read_cell.running_disabled = running_disabled
read_cell.depends_on_disabled_cells = depends_on_disabled_cells || running_disabled
lungben marked this conversation as resolved.
Show resolved Hide resolved
collected_cells[cell_id] = read_cell
end
end
Expand Down