Почему одна и та же функция Firebase должна работать в 10 раз дольше при использовании триггера schedule / onRun, чем триггера HTTP onRequest? - PullRequest
0 голосов
/ 01 мая 2020

У меня есть 2 идентичные функции Firebase, которые выполняют пакетную запись данных в Firestore. Один из них заключен в триггер по расписанию / onRun, а другой - в триггер HTTP onRequest.

Обе функции работают нормально и не выдают ошибок.

Они также имеют одинаковый объем памяти и время ожидания.

При вызове триггера http функция запускается и завершается примерно через 30 секунд.

При вызове запланированного триггера onRun для завершения функции требуется более 5 минут.

Есть ли что-то другое во время выполнения, которое не задокументировано или что-то в этом роде?

Редактировать: теперь это работает - я сделал processMentions ожидающими totalMentions и вернул null.

processMentions не должен возвращать обещание, только значение, потому что фактическая функция schedulePull / onRun возвращает processMentions асин * Функция 1024 *, которая разрешает обещание путем возврата значения.

Приветствия за помощь @ dougstevenson

Триггеры:

/**
 * Get manual mentions 
 */
exports.get = functions.https.onRequest((req, res) => {
  const topic = 'topic'
  const query = 'queryString'
  processMentions(res, query, topic)
})

/**
 * Get schedule mentions 
 */
exports.scheduledPull = functions.pubsub.schedule('every day 1:00').onRun((context) => {
    const topic = 'topic'
    const query = 'queryString'
    return processMentions('sched', query, topic)
  })

Logi c:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
const db = admin.firestore()
const axios = require('axios')
const moment = require('moment')

// Globals
const auth = 'token'
const url = 'https://apiurl.com/'

async function totalMentions(nextPage, start, end, query) {
  try {
    let config = {
      headers: {
        Authorization: auth,
        Accept: 'text/html',
      }
    }
    const response = await axios.get(url, config)
    const total = response.data.results.total
    const loops = Math.ceil(total / 500)
    return loops
  } catch (error) {
    console.log('error 1', error)
  }
}

async function allMentions(nextPage, start, end, query) {
  try {
    let config = {
      headers: {
        Authorization: auth,
        Accept: 'text/html',
      },
    }
    const response = await axios.get(url, config)
    return response
  } catch (error) {
    console.log('error 2', error)
  }
}

async function saveData(response, end, topic) {
  try {
    let data = await response.data.results.clips
    let batch = db.batch()
    data.forEach((c) => {
      delete c.localTime
        let reff = db.collection(collection).doc(date).collection(collection).doc(c.id.toString())
        batch.set(reff, c)
    })
    let batches = await batch.commit()
    return batches
  } catch (error) {
    console.log('error3 ', error)
  }
}

async function processMentions(res, query, topic) {
  try {
    totalMentions(1, start, end, query)
      .then(async (loops) => {
        let endbatch = 0
        for (let i = 1; i <= loops; i++) {
          await allMentions(i, start, end, query)
            .then(async (response) => {
              await saveData(response, end, topic)
              return ++endbatch
            })
            .catch((err) => {
              console.log('error 4 ' + err)
            })
          if (endbatch === loops) {
            if (res !== 'sched') {
              console.log('http trigger finished')
              return res.status(200).end()
            } else {
              return console.log('schedule finished')
            }
          }
        }
      })
      .catch((err) => {
        console.log('error5 ' + err)
      })
  } catch (error) {
    console.log('error6 ' + error)
  }
}

1 Ответ

1 голос
/ 01 мая 2020

Для правильной работы триггера pubsub processMentions необходимо вернуть обещание, которое восстанавливается после завершения всей работы asyn c. Прямо сейчас он ничего не возвращает, что (поскольку оно объявлено как asyn c) переводится в обещание, которое разрешается немедленно без значения. Вызов затем / поймать обещание не делает то, что вы ожидаете - вам нужно вернуть цепочку обещаний из вашей асин c работы.

Я не уверен, почему вы объявили асин c без использования внутри него await для более простого управления обещаниями.

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