Sharp: Source file remains locked in node forever

Created on 27 Jan 2016  路  5Comments  路  Source: lovell/sharp

I intend to use sharp to optimize images uploaded onto an SQL database. The obvious benefit is retrieving speed for a small cost of resizing it.
So in SQL i have a trigger that dumps the image content into a monitored folder. If it meets some criteria it gets converted. Anyhow the image is always deleted to avoid a million plus big images. When the criteria are not met the file is not processed by sharp and can be deleted. If however it does gets processed it does refuse to be deleted with message of EBUSY. Notice that using Explorer delete gives a similar message that the file is in use.

Relevant section:

sharp(fileIn)
.resize(380, 538)
.ignoreAspectRatio()
.quality(40)
.jpeg()
.progressive()
.toFile( fileOut, (err) => {
if (err) {
console.log('Error ' + fileOut + ' ' + err.toString());
} else {
console.log('made ' + fileOut);
fs.unlink(fileIn, (err) => { if (err) {
console.log('error deleting ' + fileIn + ' ' + err.toString());
} else {
console.log('deleted ' + fileIn);
}
}
);
}
});

This error remains till Node is stopped. Aka it appears Sharp never closes the file handle. This might also explain heavy load issues that I also experienced.

question

All 5 comments

Hello, my best guess is that the file is being held open in libvips' cache.

Are you able to try the improved cache method available on the mind branch? You can use npm install lovell/sharp#mind to install from that branch.

If so, use it to set options.files to zero, something like sharp.cache( { files: 0 } );

will try :D

Yup I can confirm that the files are locked. The work around is easy. Just read the file yourself and pass the buffer.
Like

fs.readFile(fileIn, (err,data) => {
if (err) {
console.log('Error reading file ' + fileIn + ' ' + err.toString());
} else {
sharp(data)
.quality(40)
.jpeg()
.toFile( fileOut, (err) => {
if (err) {
console.log('Error ' + fileOut + ' ' + err.toString());
} else {
console.log('made ' + fileOut);
fs.unlink(fileIn, (err) => { if (err) {
console.log('error deleting ' + fileIn + ' ' + err.toString());
} else {
console.log('deleted ' + fileIn);
}
}
);
}
});
}
});

Thanks for confirming. The extra control provided by the cache method on the mind branch will be included in the v0.13.0 release.

When using the same input file to generate lots of different output files, libvips' cache can increase performance by caching (regions of) the decompressed input image. You won't see the same benefits when using Buffer objects, but that might not be a problem.

Hello I managed to make it work by settings cache to 0 but If I access the same file two times, I once again have it locked... Any fix?

Was this page helpful?
0 / 5 - 0 ratings