Обработка изображений Google Cloud Functions занимает минуты для обработки изображений

Что я делаю с облачными функциями:

  1. Загрузка URL-адреса в каталог /tmp.
  2. Запуск конвертирования для создания эскиза максимального размера (600*600).
  3. Хранение в хранилище Firebase.
  4. Обратная запись в базу данных Firebase в реальном времени.

Вся операция занимает около 2-3 минут, и если я выполняю 5-6 функций параллельно, только 1-2 завершаются. Вот код. Подскажите, пожалуйста, что можно сделать в этом:

'use strict';

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const LOCAL_TMP_FOLDER = '/tmp/';

// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';

const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='-----------';
//const THUMB_SUFFIX = '_thumb';

exports.moderator = functions.database
    .ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
      const photo_data = event.data.val();
      if(!photo_data){
        return;
      }
      const user_id=event.params.user_id;
      const fileName=`${event.params.photo_processing_id}.jpg`;
      const fileLocation=`/tmp/${fileName}`;
      const modifiedfileName=`${event.params.user_id}_${fileName}`;
      const modifiedfileLocation=`/tmp/${modifiedfileName}`;

      console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);
      const options = {
          url: photo_data.source,
          dest: fileLocation,                  // Save to /path/to/dest/image.jpg
          done: function(err, filename, image) {
              if (err) {
                    console.log('error occured', err);
              }
              console.log('File saved to', filename);

        // Uploading the JPEG image.
         const bucket = gcs.bucket(bucket_name);
         const destinationUrl=`photos/${modifiedfileName}`;
         return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() => {
           console.log('Thumbnail created at', modifiedfileLocation);
            return bucket.upload(modifiedfileLocation, {
                destination: destinationUrl
                }).then(() => {
                console.log('JPEG image uploaded to Storage at',modifiedfileName );
                 return admin.database().ref(`/users/${user_id}/photos`).push(destinationUrl);
        });
      })
      }
    }
      image_downloader(options);

  });

person shashuec    schedule 02.04.2017    source источник


Ответы (1)


Я смог решить эту проблему. Проблема в том, что облачная функция должна возвращать обещание, иначе они ведут себя странно.

Вот рабочее решение:

'use strict';

const functions = require('firebase-functions');
//const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const LOCAL_TMP_FOLDER = '/tmp/';

// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';

const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='--------';
//const THUMB_SUFFIX = '_thumb';

const fetch=(source,filename,fileLocation)=> new Promise((resolve,reject)=>{
  console.log("details passed to fetch method",source,filename,fileLocation);

  const options = {
      url: source,
      dest: fileLocation,                  // Save to /path/to/dest/image.jpg
      done: function(err, filename, image) {
          if (err) {
                reject(err);
                console.log('error occured', err);
          }
          resolve(filename);
          console.log('File saved to', filename);
        }
  }

    image_downloader(options);
});


exports.moderator = functions.database
    .ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
      const photo_data = event.data.val();
      if(!photo_data){
        return;
      }
      const user_id=event.params.user_id;
      //console.log("photo data came to the firebase funciotn",photo_data);
      //console.log('user_id passed', event.params.user_id);
      //console.log('photo_processing_id passed', event.params.photo_processing_id);
      const fileName=`${event.params.photo_processing_id}.jpg`;
      const fileLocation=`/tmp/${fileName}`;
      const modifiedfileName=`${event.params.user_id}_${fileName}`;
      const modifiedfileLocation=`/tmp/${modifiedfileName}`;
      const is_profile=photo_data.is_profile;
      const created_time=photo_data.created_time;
      console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);

      const bucket = gcs.bucket(bucket_name);
      const destinationUrl=`photos/${modifiedfileName}`;
      return fetch(photo_data.source,fileName,fileLocation).then(()=>
        {
          return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() =>
          {
            console.log('Thumbnail created at', modifiedfileLocation);
            return bucket.upload(modifiedfileLocation, {
             destination: destinationUrl
             }).then(() => {
                  console.log('JPEG image uploaded to Storage at',modifiedfileName );
                  const photo_data_to_save={url:destinationUrl,created_time};
                  if(is_profile){
                    photo_data_to_save.is_profile=true;
                  }
                   admin.database().ref(`/users/${user_id}/userData/photos`).push(photo_data_to_save);
                   return null;
                })

     });
   })
  });
person shashuec    schedule 04.04.2017
comment
Вы когда-нибудь выясняли причину, почему это происходило? У меня та же проблема, но возврат обещания не решает ее (порождение уже является обещанием) - person CodeKiwi; 24.07.2017