An Elixir integration with libVIPS
MIT License
The Supervised Scaler is an Elixir/Phoenix project made to support my lightning talk at Elixir London 2016. It is laid out thusly:
scaler
, which generates thumbnails using a local dependency.resampler
which contains an Elixir wrapper around a C server, which calls libVIPS.mogrify
library that renders a reference thumbnail.This project is considered alpha quality and should not yet be used in production systems, because I have not fulfilled items listed under Help Wanted. If you are willing to use this in production, though, Id like to read your crash logs.
To be brief, the C API for libVIPS is used and a C program listens on STDIN for image resampling requests. Each request uses a full line with a line break at the end, which is incidentally also the unit of work read in by the C program. The program then attempts to locate the file, resize it, allocate a temporary file path and write the output into that path. Once done the program emits the path via STDOUT; in case of any error exactly one message will be logged via STDERR.
This C program is then run under erlexec from a GenServer and that is further mediated by poolboy. I then configure erlexec
to use run_link
so any sort of segmentation fault or other unsavoury business in the C program simply causes the entire thing to die and be replaced with another fresh worker by poolboy.
Then I put in an interface which checks out a process from poolboy
and calls the resultant GenServer in question, asking for it to convert a file. The GenServer then sends a message to the C server via erlexec
in STDIN and uses a nested receive
to glean whatever response provided, and ultimately pass that piece of information back to the caller.
I believe that this is the most straightforward solution to deliver a solution that is fast (it is quite hard to beat libVIPS), simple (even the C server does not need defensive programming any more, since if it crashes a new one replaces it anyway), and straightforward to use (the public API uses a single call).
pkg-config
reports it properly. See: pkg-config --libs --cflags vips
.resampler
from deps_local
. (Note: once we have a proper entry in the package manager this will change.)Resampler.Pool
as part of your applications supervision tree.{:ok, file_path} = Resampler.request(path, maxWidth, maxHeight)
.Open an Issue and Ill look at them whenever I can.
erlexec
vs. pty
vs. fgets
. See issue in erlexec.mix.exs
.erlexec
mogrify
for use in Elixir