Skip to content

Commit

Permalink
🛹 Performance
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsp committed May 11, 2020
1 parent 6646ac7 commit f6709f9
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Pluto"
uuid = "c3e4b0f8-55cb-11ea-2926-15256bba5781"
license = "MIT"
authors = ["Fons van der Plas <[email protected]>", "MikoÅ‚aj Bochenski <[email protected]>"]
version = "0.8.5"
version = "0.8.6"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
2 changes: 1 addition & 1 deletion assets/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class PlutoConnection {
}
this.psocket.onopen = () => {
this.sendreceive("connect", {}).then(u => {
this.plutoCONFIG = u.message.CONFIG
this.plutoENV = u.message.ENV
if(this.notebookID && !u.message.notebookExists){
// https://github.com/fonsp/Pluto.jl/issues/55
document.location.href = "./"
Expand Down
4 changes: 2 additions & 2 deletions assets/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ function updateLocalCellOutput(cellNode, msg) {

// convert LaTeX to svg
try{
MathJax.typeset()
MathJax.typeset([containerNode])
} catch(err) {
console.info("Failed to typeset TeX:")
console.info(err)
Expand Down Expand Up @@ -553,7 +553,7 @@ function onUpdate(update, byMe) {
window.customPlutoListeners = {}

function onEstablishConnection() {
const runAll = client.plutoCONFIG["PLUTO_RUN_NOTEBOOK_ON_LOAD"] == "true"
const runAll = client.plutoENV["PLUTO_RUN_NOTEBOOK_ON_LOAD"] == "true"
// on socket success
client.send("getallnotebooks", {})

Expand Down
4 changes: 3 additions & 1 deletion src/Pluto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ export Notebook, Cell, run
import Pkg

const PKG_ROOT_DIR = normpath(joinpath(@__DIR__, ".."))
include_dependency(joinpath(PKG_ROOT_DIR, "Project.toml"))
const PLUTO_VERSION = VersionNumber(Pkg.TOML.parsefile(joinpath(PKG_ROOT_DIR, "Project.toml"))["version"])
const PLUTO_VERSION_STR = 'v' * string(PLUTO_VERSION)
const JULIA_VERSION_STR = 'v' * string(VERSION)
const CONFIG = Dict(
const ENV_DEFAULTS = Dict(
"PLUTO_WORKSPACE_USE_DISTRIBUTED" => "true",
"PLUTO_RUN_NOTEBOOK_ON_LOAD" => "true",
"PLUTO_ROOT_URL" => "/",
)
Expand Down
2 changes: 1 addition & 1 deletion src/notebookserver/Notebook.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function load_notebook(path::String)
update_caches!(loaded, loaded.cells)
save_notebook(loaded)
# Clear symstates if autorun is disabled. Otherwise running a single cell for the first time will also run downstream cells.
if CONFIG["PLUTO_RUN_NOTEBOOK_ON_LOAD"] != "true"
if ENV["PLUTO_RUN_NOTEBOOK_ON_LOAD"] != "true"
for cell in loaded.cells
cell.symstate = SymbolsState()
end
Expand Down
25 changes: 7 additions & 18 deletions src/react/WorkspaceManager.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ Workspace(workspace_pid::Integer, module_name::Symbol) = let
Workspace(workspace_pid, module_name, t)
end

"Should future workspaces be created on a separate process (`true`) or on the same one (`false`)?
Only workspaces on a separate process can be stopped during execution. Windows currently supports `true` only partially: you can't stop cells on Windows."
function set_default_distributed(val::Bool)
global default_distributed = val
end

function reset_default_distributed()
global default_distributed = Sys.iswindows() ? false : true
end

reset_default_distributed()

"These expressions get executed whenever a new workspace is created."
const workspace_preamble = [
:(using Markdown, Main.PlutoRunner),
Expand All @@ -45,8 +32,10 @@ moduleworkspace_count = 0
workspaces = Dict{UUID,Workspace}()


"Create a workspace for the notebook, optionally in a separate process."
function make_workspace(notebook::Notebook, new_process = default_distributed)::Workspace
"""Create a workspace for the notebook, optionally in a separate process.
`new_process`: Should future workspaces be created on a separate process (`true`) or on the same one (`false`)? Only workspaces on a separate process can be stopped during execution. Windows currently supports `true` only partially: you can't stop cells on Windows. _Defaults to `ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"]`_"""
function make_workspace(notebook::Notebook, new_process = (ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"] == "true"))::Workspace
pid = if new_process
create_workspaceprocess()
else
Expand Down Expand Up @@ -178,10 +167,10 @@ function eval_fetch_in_workspace(workspace::Workspace, expr::Any, ends_with_semi
@assert ex.pid == workspace.workspace_pid
@assert ex.captured.ex isa InterruptException

return (output_formatted = PlutoRunner.format_output(InterruptException()), errored = true, interrupted = true, runtime=missing, declared_assignments=Set{Symbol}(), declared_references=Set{Symbol}())
return (output_formatted = PlutoRunner.format_output(InterruptException()), errored = true, interrupted = true, runtime=missing)
catch assertionerr
showerror(stderr, exs)
return (output_formatted = PlutoRunner.format_output(exs), errored = true, interrupted = true, runtime=missing, declared_assignments=Set{Symbol}(), declared_references=Set{Symbol}())
return (output_formatted = PlutoRunner.format_output(exs), errored = true, interrupted = true, runtime=missing)
end
end

Expand Down Expand Up @@ -243,7 +232,7 @@ function kill_workspace(workspace::Workspace)
return false
end
if workspace.workspace_pid == Distributed.myid()
@warn "Cells in this workspace can't be stopped, because it is not running in a separate workspace. Use `set_default_distributed` to control whether future workspaces are generated in a separate process."
@warn """Cells in this workspace can't be stopped, because it is not running in a separate workspace. Use `ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"]` to control whether future workspaces are generated in a separate process."""
end

# You can force kill a julia process by pressing Ctrl+C five times 🙃
Expand Down
9 changes: 6 additions & 3 deletions src/runner/PlutoRunner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,17 @@ struct 🥔 end
const struct_showmethod = which(show, (IO, 🥔))
const struct_showmethod_mime = which(show, (IO, MIME"text/plain", 🥔))

function show_richest(io::IO, @nospecialize(x); onlyhtml::Bool=false)
mime = first(filter(m->Base.invokelatest(showable, m, x), allmimes))
function show_richest(io::IO, @nospecialize(x); onlyhtml::Bool=false)::MIME
mime = allmimes[findfirst(m -> Base.invokelatest(showable, m, x), allmimes)]
t = typeof(x)

if mime isa MIME"text/plain" &&
isstruct =
mime isa MIME"text/plain" &&
t isa DataType &&
which(show, (IO, MIME"text/plain", t)) === struct_showmethod_mime &&
which(show, (IO, t)) === struct_showmethod

if isstruct
# we have a struct with no specialised show function
# we display it as an interactive tree
show_struct(io, x)
Expand Down
2 changes: 1 addition & 1 deletion src/webserver/Dynamic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ end
responses[:connect] = (body, notebook=nothing; initiator::Union{Initiator, Missing}=missing) -> begin
putclientupdates!(initiator, UpdateMessage(:👋, Dict(
:notebookExists => (notebook != nothing),
:CONFIG => CONFIG,
:ENV => filter(p -> startswith(p.first, "PLUTO"), ENV),
), nothing, nothing, initiator))
end

Expand Down
12 changes: 4 additions & 8 deletions src/webserver/Static.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ const PLUTOROUTER = HTTP.Router()

function notebook_redirect(notebook)
response = HTTP.Response(302, "")
push!(response.headers, "Location" => CONFIG["PLUTO_ROOT_URL"] * "edit?uuid=" * string(notebook.uuid))
push!(response.headers, "Location" => ENV["PLUTO_ROOT_URL"] * "edit?uuid=" * string(notebook.uuid))
return response
end

function serve_sample(req::HTTP.Request)
uri=HTTP.URI(req.target)

uri = HTTP.URI(req.target)
path = split(uri.path, "sample/")[2]
try
nb = load_notebook_nobackup(joinpath(PKG_ROOT_DIR, "sample", path))
Expand All @@ -57,13 +56,12 @@ function serve_sample(req::HTTP.Request)
end

function serve_openfile(req::HTTP.Request)
uri=HTTP.URI(req.target)
uri = HTTP.URI(req.target)
query = HTTP.URIs.unescapeuri(replace(uri.query, '+' => ' '))

if length(query) > 5
path = tamepath(query[6:end])

if(isfile(path))
if (isfile(path))
try
for nb in values(notebooks)
if realpath(nb.path) == realpath(path)
Expand All @@ -75,11 +73,9 @@ function serve_openfile(req::HTTP.Request)
save_notebook(nb)
notebooks[nb.uuid] = nb
return notebook_redirect(nb)

catch e
return HTTP.Response(500, "Failed to load notebook:\n\n$(e)\n\n<a href=\"/\">Go back</a>")
end
# return HTTP.Response(200, """<head><meta charset="utf-8" /></head><body>Path: $(path)</bodu>""")
else
return HTTP.Response(404, "Can't find a file here.\n\n<a href=\"/\">Go back</a>")
end
Expand Down
11 changes: 9 additions & 2 deletions src/webserver/WebServer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ function endswith(vec::Vector{T}, suffix::Vector{T}) where T
liv >= lis && (view(vec, (liv-lis + 1):liv) == suffix)
end

function set_ENV_defaults()
for pair in ENV_DEFAULTS
haskey(ENV, pair.first) || setindex!(ENV, pair.second, pair.first)
end
end

const connectedclients = Dict{Symbol,Client}()
const notebooks = Dict{UUID,Notebook}()

Expand Down Expand Up @@ -117,6 +123,7 @@ const MSG_DELIM = "IUUQ.km jt ejggjdvmu vhi" # riddle me this, Julius
This will start the static HTTP server and a WebSocket server. Pluto Notebooks will be started dynamically (by user input)."""
function run(host, port::Integer; launchbrowser::Bool = false)
set_ENV_defaults()
hostIP = parse(Sockets.IPAddr, host)
serversocket = Sockets.listen(hostIP, UInt16(port))
servertask = @async HTTP.serve(hostIP, UInt16(port), stream = true, server = serversocket) do http::HTTP.Stream
Expand Down Expand Up @@ -206,12 +213,12 @@ function run(host, port::Integer; launchbrowser::Bool = false)
end
end

address = if CONFIG["PLUTO_ROOT_URL"] == "/"
address = if ENV["PLUTO_ROOT_URL"] == "/"
hostPretty = (hostStr = string(hostIP)) == "127.0.0.1" ? "localhost" : hostStr
portPretty = Int(port)
"http://$(hostPretty):$(portPretty)/"
else
CONFIG["PLUTO_ROOT_URL"]
ENV["PLUTO_ROOT_URL"]
end
println("Go to $address to start writing ~ have fun!")
println()
Expand Down
22 changes: 11 additions & 11 deletions test/React.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
using Test
using Pluto
import Pluto: Notebook, Client, run_reactive!, Cell, WorkspaceManager
import Distributed

# to_test = [WorkspaceManager.ModuleWorkspace]
# if Sys.iswindows()
# println("Can't test ProcessWorkspace on Windows")
# else
# push!(to_test, WorkspaceManager.ProcessWorkspace)
# end
WorkspaceManager.set_default_distributed(false)
ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"] = "false"

@testset "Reactivity" begin
fakeclient = Client(:fake, nothing)
Expand All @@ -17,7 +12,7 @@ WorkspaceManager.set_default_distributed(false)


@testset "Basic $(parallel ? "distributed" : "single-process")" for parallel in [false, true]
WorkspaceManager.set_default_distributed(parallel)
ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"] = string(parallel)

notebook = Notebook([
Cell("x = 1"),
Expand All @@ -30,11 +25,13 @@ WorkspaceManager.set_default_distributed(false)
g(a,b) = y
end"""),
Cell("g(6) + g(6,6)"),

Cell("import Distributed"),
Cell("Distributed.myid()"),
])
fakeclient.connected_notebook = notebook

@test !haskey(WorkspaceManager.workspaces, notebook.uuid)
# @test WorkspaceManager.get_workspace(notebook) isa method

run_reactive!(notebook, notebook.cells[1:2])
@test notebook.cells[1].output_repr == notebook.cells[2].output_repr
Expand Down Expand Up @@ -72,10 +69,13 @@ WorkspaceManager.set_default_distributed(false)
run_reactive!(notebook, notebook.cells[1])
@test notebook.cells[6].output_repr == "3"

run_reactive!(notebook, notebook.cells[7:8])
@test xor(parallel, notebook.cells[8].output_repr == string(Distributed.myid()))

WorkspaceManager.unmake_workspace(notebook)
end

WorkspaceManager.set_default_distributed(false)
ENV["PLUTO_WORKSPACE_USE_DISTRIBUTED"] = "false"


# https://github.com/fonsp/Pluto.jl/issues/32
Expand Down Expand Up @@ -623,4 +623,4 @@ WorkspaceManager.set_default_distributed(false)
end
end

WorkspaceManager.reset_default_distributed()
Pluto.set_ENV_defaults()
6 changes: 4 additions & 2 deletions test/helpers.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Pluto
import Pluto.ExploreExpression: SymbolsState, compute_symbolreferences


"Calls `ExploreExpression.compute_symbolreferences` on the given `expr` and test the found SymbolsState against a given one, with convient syntax.
# Example
Expand Down Expand Up @@ -105,4 +105,6 @@ function num_backups_in(dir::AbstractString)
count(readdir(dir)) do fn
occursin("backup", fn)
end
end
end

Pluto.set_ENV_defaults()

2 comments on commit f6709f9

@fonsp
Copy link
Owner Author

@fonsp fonsp commented on f6709f9 May 11, 2020

Choose a reason for hiding this comment

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

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/14592

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.6 -m "<description of version>" f6709f9108cd744bfb6782ccfaa98fb403719bda
git push origin v0.8.6

Please sign in to comment.