Итак, у меня запущен контейнер kubernetes, подключенный к корзине Google Cloud Storage. Общая функциональность:
ON object change notification:
IF this is a new file THEN
process the file
delete the file from the bucket
ENDIF
Работает, но если я начну выбрасывать несколько файлов в корзину, уведомление для определенного файла может снова сработать, хотя сразу же произойдет сбой, поскольку файл был удален , Если я выбрасываю 20 файлов в корзину, это происходит 4 или 5 раз. Так что мои файлы обрабатываются правильно, но меня беспокоят дополнительные ошибки.
Есть ли способ для меня, в коде javascript, указать, что файл был обработан, так что уведомление не ' не запускается снова?
Вот код, который я использую (обрезан для удобства чтения):
module.exports.processListingImage = (event, context) => {
const file = event.data;
if (file.resourceState === 'not_exists') return Promise.resolve( `main: This is a deletion event: ${file.name}\n` );
if (!file.name) return Promise.resolve( `main: This is a deploy event\n` );
// FILENAME VALIDATIONS REMOVED FOR CLARITY
// The input and output buckets
const sourceBucket = file.bucket;
const destinationBucket = storage.bucket( MLS_IMAGE_BUCKET );
// get the MLS id, MLS no, and file number from the file path
const inputFilename = file.name;
let mlsId = path.dirname( inputFilename );
let extension = path.extname( inputFilename );
let bareFilename = path.basename( inputFilename, extension );
let pieces = bareFilename.split( '_' );
let mlsNo = pieces[0];
let fileNo = pieces[1];
// direct bucket access to the file so we can download it
const sourceFile = storage.bucket(sourceBucket).file(file.name);
let imageInfo = { 'mlsId': mlsId,
'mlsNo': mlsNo,
'fileNo': fileNo,
'fileSizeList': JSON.parse( IMAGE_FILE_SIZES ),
'sourceFile': sourceFile,
'destinationBucket': destinationBucket
};
// Invoke code for resizing the image
return resizeImage( imageInfo )
.then( ( stuff ) => {
return markImageProcessed({'mlsId':mlsId, 'mlsNo':mlsNo, 'fileNo':fileNo});
})
.catch( (err) => {
console.log(`markImageProcessed failed :: ${mlsId} : ${mlsNo} : ${fileNo}: `, err);
return Promise.reject('mark image failure: ', err);
})
.then( ( stuff ) => {
console.log(`main: All done, deleting original file :: ${mlsId} : ${mlsNo} : ${fileNo}:`, stuff);
return sourceFile.delete(); // returns a promise
})
.catch( (err) => {
console.log(`catchall :: ${mlsId} : ${mlsNo} : ${fileNo}: `, err);
return Promise.reject('imageProcess failure: ', err);
});
} // end exported function processListingImage();
Примечания:
resizeImage () загружает изображение из GCS , затем использует GraphicsMagick для создания нескольких размеров передаваемого изображения.
markImageProcessed () устанавливает соединение с базой данных mySQL для записи, когда все закончено
в соответствии с документацией, удалите () в файловом объекте Google Cloud Storage возвращает Promise
Таким образом, вывод выглядит примерно так: серия сообщений из моего кода об обработке:
START: Id: <full bucket/filename>
back from resizeimage :: AK-JUNEAU : 19098 : 009
markImageProcessed all done :: AK-JUNEAU : 19098 : 009:
main: All done, deleting original file :: AK-JUNEAU : 19098 : 009:
200 OK
Перемежается вызовами для удаления файла (в конце обработки):
START: <full bucket/filename>
[160] Final Status: main: This is a deletion event: AK-JUNEAU/19098_009.jpg
Но после обработки большинства файлов я начинаю получать:
Error: No such object: idx-photos-raw-gs.ihousedev.com/AK-JUNEAU/19226_004.jpg
Система по какой-то причине снова вызвал мой код обработки для файла, который уже прошел обработку и был удален в конце. Кажется, это происходит 2 или 3 раза для каждого файла, который я обрабатываю. Мне было интересно, есть ли что-то еще, что мне нужно сделать, чтобы GCS прекратил запускать мою функцию. Когда дело доходит до производства, каждый день будут обрабатываться сотни тысяч файлов, поэтому все эти дополнительные вызовы, вероятно, будут дорогими.