Запуск нескольких операторов bigquery последовательно в облачной функции - PullRequest
0 голосов
/ 31 октября 2019

У меня есть запланированная облачная функция, которая предназначена для извлечения незавершенных чередующихся транзакций из bigquery, оплаты с помощью stripe, а затем обновления bigquery с информацией о начислении. Когда я выполняю их вместе, последний запрос на обновление не завершается должным образом. Я думаю, что это связано с природой асинхронных операторов bigquery.

В основном я пытался «связать обещания», но я думаю, что, поскольку они работают асинхронно, они не заканчиваются в последовательности, вот чтоЯ хочу. Мне нужен второй шаг, который запускает полосовые сборы, чтобы завершить полностью, а затем использовать этот ответ в третьем обещании для обновления bigquery. Точно так же мне нужна вся облачная функция, чтобы дождаться завершения обновления в bigquery перед завершением.

exports.testBatchStripeCharge = functions.pubsub.schedule('05 09 * * *')
  .timeZone('America/New_York')
  .onRun((context) => {

   //This Query Selects The Rows
   async function selectQuery() {

     const selectOrders = 
     `SELECT user_id, business_id, SUM (sales) as total, stripe_id FROM 
     \`myDataSet.TableId\` WHERE is_cancelled = false AND payment_complete = 
     false group by user_id, business_id, stripe_id`

     const options = {
      query: selectOrders,
      location: 'US',
     };

     const [rows] = await bigqueryClient.query(options);
     return rows
   }

    //This Query inserts data after charges completed
    async function insertToCompletedCharges(someUserId, someBusinessId, 
      someTotal, someStripeId, someTimestamp, someStripeChargeId){

         var newTotal = Number(parseFloat(someTotal * 0.01).toFixed(2))
         const insertCharges =
            `INSERT INTO \`myDataSet.OtherTable\` (user_id, business_id, 
              grand_total, stripe_id, stripe_charge_id)
              VALUES
             ('${someUserId}', '${someBusinessId}', ${newTotal}, 
              '${someStripeId}', '${someStripeChargeId}')
            `
            const options = {
                query: insertCharges,
                location: 'US',
            };
            // Run the update query
            const [rows] = await bigqueryClient.query(options);
    }


   //This function makes the stripe charges with the selected row data
   function makeCharges(someUserId, someBusinessId, someTotal, someStripeId){

       StripeTest.charges.create({
        amount: parseFloat(someTotal).toFixed(2) * 100,
        currency: 'usd',
        description: 'test charge from cloud function',
        customer: someStripeId,
        metadata: {'user_id': someUserId, 'business_id': someBusinessId}})

       .then( response => {
          //WITH THE SUCCESSFUL STRIPE CHARGE RESPONSES INSERT TO BIGQUERY
          return insertToCompletedCharges(response.metadata.user_id, 
          response.metadata.business_id, response.amount, response.customer, 
          startOfDay, response.id)
          })

        .catch(err => {
          console.log('Error!!!', err);
          return
        });
    }

    //RUN THE QUERY TO KICK OFF THE CHAIN OF EVENTS!!!!
    return selectQuery()
        .then(rows => {
             //Loop through each row to make the charge
             //makeCharges will in turn insert updated data into bigquery 
             for (let i =0; i< rows.length; i++){
                console.log('row number', i)
                makeCharges(rows[i].user_id, rows[i].business_id, 
                rows[i].grand_total, rows[i].stripe_id)
            }
            return rows
        })  
        .catch(error => {
            console.log('error')
        })
});

Я ожидаю увидеть успешные обвинения, вставленные в bigquery для каждого ответа, который возвращает полоса API. Хотя похоже, что шаг insertToCompletedCharges не заканчивается для каждого заряда. Когда я проверяю BigQuery, иногда все обвинения будут вставлены, иногда около половины. Так что в целом что-то не заканчивается должным образом.

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