Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 16 additions & 7 deletions src/SPHCellList.jl
Original file line number Diff line number Diff line change
Expand Up @@ -851,30 +851,39 @@ using TimerOutputs: @timeit
function RunWithSimulationFinalizer!(RunFunction, SimMetaData, SimLogger, output)
OutputFinalized = Ref(false)

function FinalizeOnce!(log_status::String)
if !OutputFinalized[]
FinalizeSimulationOutput!(SimMetaData, SimLogger, output; log_status=log_status)
OutputFinalized[] = true
end
return nothing
end

atexit() do
if !OutputFinalized[]
@warn "Julia is exiting before the simulation completed; closing VTKHDF output, finalizing the log, and opening ParaView for the data written so far."
FinalizeSimulationOutput!(SimMetaData, SimLogger, output; log_status="stopped as Julia exited")
OutputFinalized[] = true
FinalizeOnce!("stopped as Julia exited")
end
end

Base.exit_on_sigint(false)

# This is the smallest reliable Ctrl+C boundary for REPL/VS Code/terminal
# execution: without catching `InterruptException`, Julia returns control
# to the caller and the `atexit` hook is not guaranteed to run.
# to the caller and the `atexit` hook is not guaranteed to run. The same
# boundary also closes VTKHDF files for ordinary simulation failures
# before rethrowing the original error to the caller.
try
RunFunction(OutputFinalized)
catch e
if e isa InterruptException
@warn "Simulation interrupted; closing VTKHDF output, finalizing the log, and opening ParaView for the data written so far."
if !OutputFinalized[]
FinalizeSimulationOutput!(SimMetaData, SimLogger, output; log_status="interrupted")
OutputFinalized[] = true
end
FinalizeOnce!("interrupted")
return nothing
end

@warn "Simulation failed; closing VTKHDF output, finalizing the log, and opening ParaView for the data written so far." exception=(e, catch_backtrace())
FinalizeOnce!("failed")
rethrow()
end

Expand Down
23 changes: 23 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,26 @@ end
@test particles.Velocity[1][1] == 0
@test particles.Velocity[1][2] < 0
end

@testset "simulation failure finalizes output" begin
mktempdir() do dir
meta = SimulationMetaData{2,Float64}(
SimulationName="failfinalizer",
SaveLocation=dir,
VisualizeInParaview=false,
OpenLogFile=false,
)
logger = SimulationLogger(dir; to_console=false)
closed = Ref(false)
output = (
close_files = () -> (closed[] = true; nothing),
variable_names = String[],
)

@test_throws ErrorException SPHExample.SPHCellList.RunWithSimulationFinalizer!(meta, logger, output) do _
error("boom")
end
@test closed[]
close(logger.LoggerIo)
end
end