Функция Cloud перестает выполняться при использовании объекта Batch - PullRequest
0 голосов
/ 19 января 2019

Я использую облачную функцию Google, чтобы выполнить запрос к bigQuery и сохранить результат в firestore.

Моя проблема заключается в том, что, как только я пытаюсь использовать пакетный объект firestore, облачная функция перестает выполнять.

Используя дихотомию, я думаю, что когда я включаю пакетный объектный код, функция внезапно перестает работать.

Я попытался увеличить память функции до 1 ГБ без удачи.(в настоящее время используется 128 МБ)

const {BigQuery}  = require('@google-cloud/bigquery');
const {Firestore} = require('@google-cloud/firestore');

const bigquery   = new BigQuery  ();
const firestore  = new Firestore ();

const fsCollectionName = 'ul_queteur_stats_per_year';


const queryStr = "the bigquery query";


function handleError(err){
  //skipped
}

/**
 * Triggered from a message on a Cloud Pub/Sub topic.
 *
 * @param {!Object} event Event payload.
 * @param {!Object} context Metadata for the event.
 */
exports.ULQueteurStatsPerYear = (event, context) => {
  const pubsubMessage = event.data;
  const parsedObject  = JSON.parse(Buffer.from(pubsubMessage, 'base64').toString());

  console.log("Recieved Message : "+JSON.stringify(parsedObject));
  //{ ul_id:parsedObject.ul_id }

  const queryObj = {
    query: queryStr,
    params: {
      ul_id: parsedObject.ul_id
    }
  };

  bigquery
    .query(queryObj)
    .then((data) => {
      console.log("Query Successful, # rows : "+data.length+" data[0].length:"+data[0].length);
      //rows : [{"amount":367.63,"weight":2399.3,"time_spent_in_minutes":420}]
      const rows = data[0];
      console.log("Query Successful");

      const batch       = firestore.batch();

      console.log("Batch Created ");

      console.log("Getting Collection");
      const collection  = firestore.collection(fsCollectionName);
      console.log("Getting Collection '"+fsCollectionName+"' retrieved");
      //#####################################
      for(let i=0;i<rows.length;i++)
      {
        console.log("getting a new DocId");

        const docRef = collection.doc();

        console.log("Adding to docRef='"+docRef.id+"' : "+JSON.stringify(rows[i]));
        batch.set(docRef, rows[i]);
        console.log("Added to batch");
      }


      console.log("Commiting batch insert");
      batch.commit().then(() => {
        console.log('Successfully executed batch');
      });
      //#####################################

    })
    .catch(err => {
      handleError(err);
    });

};

Ожидается:

данные вставлены в Firestore

Фактический результат:

Если я уберу код между // #####################################

Тогда я получаю каждый лог в стекдрайвере.(Первый говорит, что есть 420 строк)

Если я позволю код между // ##################################### (или только часть batch.commit (), или только часть цикла for)

Я получаю только первый журнал, а затем ничего.

Запрос выполнен успешно, # строк: 1 data [0] .length: 420

Даже если я поместил весь код в блок try / catch с помощью консоли.В журнале исключений я не вижу ошибок в драйвере стека.

Решение

Решение состоит в том, чтобы вернуть обещание bigquery.

Поэтому приведенный выше код следует изменить на:

return bigquery
.query(queryObj)
.then(...);

Спасибо Дуг за помощь!

1 Ответ

0 голосов
/ 20 января 2019

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

Вам нужно будет обратить внимание на все обещания, которые использует ваш код,включая запрос, и все пакетные коммиты.Вы не можете игнорировать любое обещание, возвращаемое любым API, иначе работа будет прекращена до того, как она будет выполнена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...