У меня есть запланированная облачная функция, которая предназначена для извлечения незавершенных чередующихся транзакций из 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, иногда все обвинения будут вставлены, иногда около половины. Так что в целом что-то не заканчивается должным образом.