Exile is an alternative to beam ports for running external programs. It provides back-pressure using non-blocking io, and tries to fix all issues associated with ports.
Rationale and issues associated with exiting approaches are mentioned here
This is another stab at solving the issues associated with running an external command. My other approach ExCmd uses named pipes for solving these issues. But, since
:file functions are blocking operations in the beam, this can cause issues. As of now, there are no non-blocking file operations available in
:file module. So the only way to do non-blocking io is using NIF/port-driver.
Exile.stream! is a stream interface for interacting with the external program. It works with both
Collectable. Apart from being compostable, stream handles closing stdin and terminating the external process.
Exile.stream!(~w(ffmpeg -i pipe:0 -f mp3 pipe:1), input: File.stream!("music_video.mkv", , 65536)) |> Stream.into(File.stream!("music.mp3")) |> Stream.run()
Key differences when compared to other middleware based libraries and port
- fixes issues associated with ports
- no more zombie process
- can selectively close stdin
- its is demand-driven (back-pressure)
- it uses
enif_selectfor asynchronous io, so it utilizes resources efficiently
- uses non-blocking read/write system calls. so it can never block the scheduler
- it does not use any middleware
- no additional os process. no performance/resource cost
- no need to install any external command
- can run many external programs in parallel without adversely affecting schedulers (when compared to ExCmd)
- stream abstraction for interacting with the external program
- should be portable across POSIX compliant operating systems (not tested)
Non-blocking io can be used for other interesting things. Such as reading named pipe (FIFO) files.
Exile.stream!(~w(cat data.pipe)) does not block schedulers so you can open hundreds of FIFO files unlike default
Please check the project page for more detail.
Note: Exile is experimental and it is still work-in-progress
feedback is welcome