diff --git a/src/Browzarr.jl b/src/Browzarr.jl index a1daf18..5965d0a 100644 --- a/src/Browzarr.jl +++ b/src/Browzarr.jl @@ -14,16 +14,23 @@ end const SERVERS = Dict{Int, BrowzarrServer}() const SERVERS_LOCK = ReentrantLock() +const DEFAULT_PORT = 3000 +const DEFAULT_AUTOPORT = true # automatically pick next port if current in use include("mimeTypes.jl") include("servers.jl") -function browzarr(; port::Int = 3000, open::Union{Bool, Nothing} = nothing, store::Union{String, Nothing} = nothing) +function browzarr(; + port::Integer = DEFAULT_PORT, + autoport::Bool = DEFAULT_AUTOPORT, + open::Union{Bool, Nothing} = nothing, + store::Union{String, Nothing} = nothing +) notebook = in_notebook() vscode = in_vscode() open_browser_flag = isnothing(open) ? !(notebook || vscode) : open - srv = start_browzarr(; port, store) + srv = start_browzarr(; port, autoport, store) if notebook && !open_browser_flag display("text/html", browzarr_iframe(srv)) diff --git a/src/servers.jl b/src/servers.jl index e63f091..bee2fb4 100644 --- a/src/servers.jl +++ b/src/servers.jl @@ -1,6 +1,22 @@ -function start_browzarr(; port::Int = 3000, host::String = "127.0.0.1", store::Union{String, Nothing} = nothing) +function start_browzarr(; + port::Integer = DEFAULT_PORT, + autoport::Bool = DEFAULT_AUTOPORT, + host::String = "127.0.0.1", + store::Union{String, Nothing} = nothing +) return lock(SERVERS_LOCK) do - haskey(SERVERS, port) && error("Server already running on port $port") + + # If autoport is enabled, keep incrementing the port number until we find a free one + while autoport && haskey(SERVERS, port) + @warn "Port $port is already in use, trying next port..." + port += 1 + end + + # If autoport is disabled and the port is already in use, throw an error + if !autoport && haskey(SERVERS, port) + error("Server already running on port $port") + end + # The `browzarr` npm tarball unpacks under `package/` and the static build lives in `out/`. dir = joinpath(artifact"Browzarr", "package", "out") handler = static_handler(dir, store) @@ -29,7 +45,7 @@ function stop!(srv::BrowzarrServer) return @info "Browzarr server stopped" port = srv.port end -function stop!(port::Int) +function stop!(port::Integer) srv = lock(SERVERS_LOCK) do get(SERVERS, port, nothing) end @@ -60,7 +76,7 @@ running_servers() = lock(SERVERS_LOCK) do collect(values(SERVERS)) end -get_server(port::Int) = lock(SERVERS_LOCK) do +get_server(port::Integer) = lock(SERVERS_LOCK) do get(SERVERS, port, nothing) end