Javascript 缩略图云功能失败,出现“0”;错误:EBUSY:资源正忙或已锁定,rmdir'/tmp/拇指';错误时(本机)“;
My Firebase Cloud函数失败,出现以下错误:Javascript 缩略图云功能失败,出现“0”;错误:EBUSY:资源正忙或已锁定,rmdir'/tmp/拇指';错误时(本机)“;,javascript,firebase,google-cloud-functions,firebase-storage,Javascript,Firebase,Google Cloud Functions,Firebase Storage,My Firebase Cloud函数失败,出现以下错误: Error: EBUSY: resource busy or locked, rmdir '/tmp/thumbs' at Error (native) 使用我的功能,我为上传的图片创建缩略图,并将其保存到Firebase存储。按照我构建以下代码的方式,一切正常(除了每个函数调用都失败)。但我担心,由于tmp文件夹中的旧文件没有被删除,我的tmp文件夹将充满不必要的文件 import * as functions from 'fire
Error: EBUSY: resource busy or locked, rmdir '/tmp/thumbs' at Error (native)
使用我的功能,我为上传的图片创建缩略图,并将其保存到Firebase存储。按照我构建以下代码的方式,一切正常(除了每个函数调用都失败)。但我担心,由于tmp文件夹中的旧文件没有被删除,我的tmp文件夹将充满不必要的文件
import * as functions from 'firebase-functions'
import {tmpdir} from 'os'
import {join, dirname} from 'path'
import * as sharp from 'sharp'
import * as fs from 'fs-extra'
import * as admin from "firebase-admin"
const storage = admin.storage()
/* Saves thumbnails for all userPics uploaded to Google Cloud Storage */
export const thumbnailCreator = functions.storage
.object()
.onFinalize(async object => {
const bucket = storage.bucket(object.bucket)
const filePath = object.name
const fileName = filePath.split('/').pop()
const bucketDir = dirname(filePath)
const workingDir = join(tmpdir(), 'thumbs')
/* Temporary: Creates a random number for the sourceFilePath
* because currently bucket.file(filePath).download does not seem to overwrite
* existing files and fs.rmdir(workingDir) does throw that error... */
const randomNr = Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15)
const tmpFilePath = join(workingDir, `source_${randomNr}.png`)
if (!object.contentType.includes('image')) {
console.log('exiting function (no image)')
return false
}
if (fileName.includes('thumb@')) {
console.log('exiting function (already a thumbnail')
return false
}
// 1. Ensure thumbnail dir exists
await fs.ensureDir(workingDir)
// 2. Download Source File
await bucket.file(filePath).download({
destination: tmpFilePath
})
// 3. Resize the images and define an array of upload promises
const sizes = [64, 128, 256, 512]
const uploadPromises = sizes.map(async size => {
const thumbName = `thumb@${size}_${fileName}`
const thumbPath = join(workingDir, thumbName)
// Resize source image
await sharp(tmpFilePath)
.rotate()
.resize(size, size)
.toFile(thumbPath)
// Upload to GCS
const file = await bucket.upload(thumbPath, {
destination: join(bucketDir, thumbName),
predefinedAcl: 'publicRead'
})
})
// 4. Run the upload operations
await Promise.all(uploadPromises)
// 5. Cleanup remove the tmp/thumbs from the filesystem
return fs.rmdir(workingDir)
// TODO: This fails every time -> also tried with fs.remove(workingDir), same issue.
})
如您所见,我处理它的方法是为source.png的文件名提供GUID,因为下次调用该函数时,在执行bucket.file(filePath).download()时,它不会覆盖已下载的文件
但是我想清理我的tmp文件夹,我不知道为什么文件夹“忙或锁定”。在尝试删除它之前,是否有方法将其解锁
更新-来自DOUG的解决方案
正如Doug在下面回答的那样,在删除文件夹之前删除所有文件是有效的。所以我就这样做了:
// 5. Cleanup remove the tmp/thumbs from the filesystem
await fs.emptyDir(workingDir)
await fs.remove(workingDir)
我不知道这是否会导致EBUSY,但是rmdir(节点的版本和同名的unix命令行)要求在调用它之前目录为空。您在其中留下了文件,这可能会导致rmdir失败。尝试分别删除每个生成的文件,然后删除目录。Thx Doug,这很有用!我忘了在上面提到,我已经用fs extra的fs.remove()
尝试过了,它应该会删除其中包含文件的文件夹,但奇怪的是,同样的错误发生了。现在先用fs.emptyDir(workingDir)
删除文件,然后用fs.remove(workingDir)
删除目录就可以了。我知道我可以相信你的皮萨兹;-)