Google Cloud Functions图像处理需要几分钟才能完成图像处理

时间:2017-04-02 11:13:07

标签: javascript firebase firebase-storage google-cloud-functions

我正在使用云功能:

  1. 将网址下载到/tmp目录。
  2. 运行转换以创建最大尺寸(600 * 600)的缩略图。
  3. 将其存储在Firebase存储中。
  4. 回写Firebase实时数据库。
  5. 整个操作需要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);
    
      });
    

1 个答案:

答案 0 :(得分:0)

我能够解决这个问题。问题是云函数应该返回一个承诺,否则它们表现得非常奇怪。

以下是工作解决方案:

'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;
                })

     });
   })
  });