Skip to content

Cleaning up resources before Process.exec #16100

@straight-shoota

Description

@straight-shoota

Process.exec replaces the current process. It happens immediately and affects everything in the process. This means there's no opportunity for any cleanup or dispatch fibers to run before it.

We've experienced a problem in shards when changing from Process.run to Process.exec: crystal-lang/shards#686 (comment) A log message emitted right before the exec call never got written because the async log dispatch fiber never has a chance to process it.

This simplified example demonstrates the problem:

require "log"

Log.info{"foo"}

Process.exec("echo bar")

The info log message doesn't appear in the output.
Adding ::Log.builder.close before the exec call fixes this.

The same problem applies at process exit. For that reason, we have an exit handler to close the log builder

at_exit { @@builder.close }

But exit handlers only run on process exit, not on exec.

I think we should have some mechanism to enable certain necessary cleanup tasks (such as processing log events) for Process.exec, similar to what we have for exit. It should not be the burden of the code that calls Process.exec to be aware of which things needs to be done before doing that safely.

Maybe we should run exit handlers before exec? In a way it's similar - the current process stops executing. Although there are some slight semantic differences, which might or might not be relevant.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions