【问题标题】:Firebase Functions "Error: memory limit exceeded. Function invocation was interrupted."Firebase 函数“错误:超出内存限制。函数调用被中断。”
【发布时间】:2019-01-08 17:41:08
【问题描述】:

有没有人在他们的 firebase 函数中遇到过以下错误(并且很确定它甚至不应该在 quota of 256 MB 附近)?

错误:超出内存限制。函数调用被中断。

函数

具体来说,它是一个基于 CRON 的每三周一次的函数,它会进行 30 次 Feedly API 调用,以检索每篇 100 篇文章的元数据(包括摘要/内容信息)。粗略计算多少数据从 Firebase 数据库中提取并推送到 Firebase 数据库,告诉我它不应该接近规定限制的一半。在使用“firebase functions:shell”进行本地测试时,它也对我有用。

这是代码的最小版本(最初大约 130 行):

const rp = require('request-promise');

var exports = module.exports = {};

exports.feedlyPull_A = functions.pubsub.topic('triweekly-tick').onPublish((event) => {
  let ps = [];
  for (var catKey in feedlyList) {
    if (feedlyList.hasOwnProperty(catKey)) {

      let read_match_details = {
        uri: 'http://cloud.feedly.com/v3/streams/contents?streamId=user%2FUSER_KEY_HERE%2Fcategory%2F' + feedlyList[catKey].key + '&count=100',
        method: 'GET',\
        headers : {
          "Authorization" : "OAUTH KEY HERE"
        },
        json: true
      };
      ps.push(rp(read_match_details));
    }
  }

  let artPromise = admin.database().ref('Article').once('value');

  return artPromise.then(results_art => {
    let articleObj = results_art.val();

    let skillPromise = admin.database().ref('Skill').once('value');

    return skillPromise.then(results_ski => {
      console.log('Skills Retrieved!');
      let skillList = results_ski.val();

      return Promise.all(ps)
      .then((results) => {
        for (var i = 0; i < results.length; i++) {
          let articles = results[i].items;

          let pathName = feedlyList[i].name;

          if (articles && Object.keys(articles).length > 0) {
            for (var key in articles) {
              // A BUNCH OF KEYWORD PARSING ON ARTICLE SUMMARY/CONTENT HERE and storing in arrays
            }

            if (artList) {
              admin.database().ref('Article/'+pathName).set(artList, (snapshot) => {
                console.log('Processed & Pushed: ' + pathName);
              });
            }
          } else {
            console.log('Failed (No articles found): ' + pathName);
          }
        }
      }).catch(err => {
        console.log(err);
      });
    });
  });
});

我对云计算很陌生,所以我有点迷失从哪里开始...有没有人能够解决/调试这样的问题,或者有什么建议?

我在想是否有办法以某种方式测量累积内存(鉴于我理解 256 MB 指的是什么),我可以根据如何解决的试错来回溯,但不知道该怎么做...

非常感谢! (这已经稍微推迟了发布计划,因此非常感谢您的帮助!)

【问题讨论】:

    标签: javascript firebase firebase-realtime-database request google-cloud-functions


    【解决方案1】:

    我不知道这是否是您的内存限制错误的根源,但您应该如下调整您的代码,以便在您的 Cloud Functions 中返回一个承诺。

    请注意,不清楚artList 的值是什么。它可能是在您为提高可读性而删除的代码部分中定义的。

    const rp = require('request-promise');
    
    var exports = module.exports = {};
    
    exports.feedlyPull_A = functions.pubsub.topic('triweekly-tick').onPublish((event) => {
      let ps = [];
      for (var catKey in feedlyList) {
        if (feedlyList.hasOwnProperty(catKey)) {
    
          let read_match_details = {
            uri: 'http://cloud.feedly.com/v3/streams/contents?streamId=user%2FUSER_KEY_HERE%2Fcategory%2F' + feedlyList[catKey].key + '&count=100',
            method: 'GET',\
            headers : {
              "Authorization" : "OAUTH KEY HERE"
            },
            json: true
          };
          ps.push(rp(read_match_details));
        }
      }
    
      let artPromise = admin.database().ref('Article').once('value');
    
      return artPromise.then(results_art => {
        let articleObj = results_art.val();
    
        let skillPromise = admin.database().ref('Skill').once('value');
    
        return skillPromise.then(results_ski => {
          console.log('Skills Retrieved!');
          let skillList = results_ski.val();
    
          return Promise.all(ps)
          .then((results) => {
    
            let promises = []; 
    
            for (var i = 0; i < results.length; i++) {
              let articles = results[i].items;
    
              let pathName = feedlyList[i].name;
    
              if (articles && Object.keys(articles).length > 0) {
                for (var key in articles) {
                  // A BUNCH OF KEYWORD PARSING ON ARTICLE SUMMARY/CONTENT HERE and storing in arrays
                }
    
                if (artList) {
                   promises.push(admin.database().ref('Article/'+pathName).set(artList));
                } else {
                  console.log('Failed (No articles found): ' + pathName);
                }
              }
            }
    
            return Promise.all(promises);
    
          }).catch(err => {
    
            console.log(err);
            return false;   //Important, see the videos I mention below
    
          });
        });
      });
    });
    

    我还建议您观看 Firebase 团队的这两个必看视频,关于 Cloud Functions 和 Promise:https://www.youtube.com/watch?v=7IkUgCLr5oAhttps://www.youtube.com/watch?v=652XeeKNHSk

    【讨论】:

    • 谢谢@renaud-tarnec!这些视频也非常有用。做了你建议的修复(完全有意义!),但我也想知道是否可以将 .then 放在 Promise.all 之后,而不是其父承诺(return SkillPromise.then(...) ,因为它出现在第三个Firebase Promises video?我仍然面临与错误相关的问题,导致我认为可能是它......
    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2019-11-28
    • 2019-09-21
    • 1970-01-01
    相关资源
    最近更新 更多