Skip to content

Commit

Permalink
basic handling of stale file handles for REPL history (#44999)
Browse files Browse the repository at this point in the history
  • Loading branch information
marmarelis authored May 9, 2022
1 parent 5e83ff5 commit d3fdde9
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ end

mutable struct REPLHistoryProvider <: HistoryProvider
history::Vector{String}
file_path::String
history_file::Union{Nothing,IO}
start_idx::Int
cur_idx::Int
Expand All @@ -536,7 +537,7 @@ mutable struct REPLHistoryProvider <: HistoryProvider
modes::Vector{Symbol}
end
REPLHistoryProvider(mode_mapping::Dict{Symbol}) =
REPLHistoryProvider(String[], nothing, 0, 0, -1, IOBuffer(),
REPLHistoryProvider(String[], "", nothing, 0, 0, -1, IOBuffer(),
nothing, mode_mapping, UInt8[])

invalid_history_message(path::String) = """
Expand All @@ -549,6 +550,12 @@ munged_history_message(path::String) = """
Invalid history file ($path) format:
An editor may have converted tabs to spaces at line """

function hist_open_file(hp::REPLHistoryProvider)
f = open(hp.file_path, read=true, write=true, create=true)
hp.history_file = f
seekend(f)
end

function hist_from_file(hp::REPLHistoryProvider, path::String)
getline(lines, i) = i > length(lines) ? "" : lines[i]
file_lines = readlines(path)
Expand Down Expand Up @@ -617,7 +624,14 @@ function add_history(hist::REPLHistoryProvider, s::PromptState)
$(replace(str, r"^"ms => "\t"))
"""
# TODO: write-lock history file
seekend(hist.history_file)
try
seekend(hist.history_file)
catch err
(err isa SystemError) || rethrow()
# File handle might get stale after a while, especially under network file systems
# If this doesn't fix it (e.g. when file is deleted), we'll end up rethrowing anyway
hist_open_file(hist)
end
print(hist.history_file, entry)
flush(hist.history_file)
nothing
Expand Down Expand Up @@ -993,11 +1007,10 @@ function setup_interface(
try
hist_path = find_hist_file()
mkpath(dirname(hist_path))
f = open(hist_path, read=true, write=true, create=true)
hp.history_file = f
seekend(f)
hp.file_path = hist_path
hist_open_file(hp)
finalizer(replc) do replc
close(f)
close(hp.history_file)
end
hist_from_file(hp, hist_path)
catch
Expand Down

0 comments on commit d3fdde9

Please sign in to comment.