简体   繁体   中英

Google Cloud Function frozen for over minute

have a strange thing happening running a Google cloud function. The function starts and logs the user id and job id as expected. Then it calls firestore db and basically sits there for 1 minute, sometimes 2 before it executes the first call... It was even timing out on 240 seconds.

 const AWS = require('aws-sdk');
 const functions = require('firebase-functions');
 const admin = require('firebase-admin');
    
 admin.initializeApp();
    
 exports.run = functions.https.onCall((data, context) => {
    
        var id = data.id;
        var userid = data.uid;
        var retry = data.retry;
    
        var project;
        var db = admin.firestore();
        var storage = admin.storage();
    
        console.log("Starting Collect");
        console.log("UID: " + userid);
        console.log("id ID: " + id);
    
        // Times out on this call 
        db.collection("users").doc(userid).collection("ids").doc(id).get().then(function(doc) {
            console.log("Loaded DB");
            project = doc.data();
            createexport();
        }).catch(function(err) {
            console.log(err);
            error('Loading DB Error, ' + err, false);
        });
    
    
        function createexport() {
            db.collection("exports").doc(id).set({
                status: 'Collecting',
                stage: 'Export Checker',
                percent: 0,
                id: id,
            }).then(function() {
                console.log("Creating Export");
                setdb();
            }).catch(function(err) {
                error("Error creating export in database :" + err, true)
            });
        }
    
        function setdb() {
            db.collection("users").doc(userid).collection("ids").doc(id).update({
                status: 'Analyzing Files',
                stage: 'Collecting'
            }).then(function() {
                getaudio();
            }).catch(function(err) {
                error("Error updating users id in database :" + err, true)
            });
        }
    
        function getaudio() {
            const from = userid + '/projects/' + project.originalproject.id + '/audio.' + project.originalproject.extension;
            const to = userid + '/' + id + '/audio.' + project.originalproject.extension;
            storage.bucket('---------').file(from).copy(storage.bucket('---------').file(to)).then(function() {
                console.log("Collecting files");
                copy2();
            }).catch(function(err) {
                error('Collecting Audio Error, ' + err, true);
            });
        }
    
        function copy2() {
            const from = userid + '/projects/' + project.originalproject.id + '/overlay.png';
            const to = userid + '/' + id + '/overlay.png';
            storage.bucket('--------.appspot.com').file(from).copy(storage.bucket('---------').file(to)).then(function() {
                updateexport();
            }).catch(function(err) {
                error('Collecting Overlay Error, ' + err, true);
            });
        }
    
    
        function updateexport() {
            db.collection("exports").doc(id).update({ status: "Waiting" }).then(function() {
                console.log("All files collected");
                return { status: 'Success' };
            }).catch(function(err) {
                error("Error creating export entry in database :" + err, true)
            });
        }
    
    
        function error(evt, evt2) {
            AWS.config.update({ region: "us-east-1" });
            var html;
            var sub = 'Error with id ' + id;
            console.log(evt);
    
            if (evt2) {
                db.collection('users').doc(userid).collection('ids').doc(id).update({
                    status: 'Error'
                }).catch(function(err) {
                    console.log(err);
                });
                db.collection("exports").doc(id).update({
                    status: 'Error',
                    stage: 'Collecting',
                    error: evt,
                }).catch(function(err) {
                    console.log(err);
                });
    
                html = `
                        Username: ${project.username} <br>
                        UserID: ${userid} <br>
                        Email: ${project.email} <br>
                        id: ${id}
                        `
            } else {
                html = `id: ${id}<br>
                        UserID: ${userid} <br>
                        Message: Error logged was: ${evt}
                        `
            }
    
            var params = {
                Destination: {
                    ToAddresses: [
                        'errors@mail.com'
                    ]
                },
                Message: {
                    Body: {
                        Html: {
                            Charset: "UTF-8",
                            Data: html
                        },
                    },
                    Subject: {
                        Charset: 'UTF-8',
                        Data: sub
                    }
                },
                Source: 'errors@mail.com',
                ReplyToAddresses: [
                    project.email
                ],
            };
            var sendPromise = new AWS.SES({
                apiVersion: "2010-12-01",
                "accessKeyId": "-----------",
                "secretAccessKey": "------------------------",
                "region": "--------",
            }).sendEmail(params).promise();
    
            sendPromise.then(function(data) {
                return { data: data };
            }).catch(function(err) {
                return { err: err };
            });
        }
    });

Seems to me to be way too long for a database call of only a few kb. I will attach the cloud log to show time difference. After this initial slump it then performs as expected. Cloud log image

Anyone got any ideas as to why this could be happening? Many thanks...

Your function is appearing to hang because it isn't handling promises correctly. Also, it doesn't appear to be sending a specific response to the client app. The main point of callable functions is to send a response.

I suggest reviewing the documentation , where you will learn that callable functions are required to return a promise that resolves with an object to send to the client app, after all the async work is complete.

Minimally, it will take a form like this:


    return db.collection("users").doc(userid).collection("files").doc(id).get().then(function(doc) {
          console.log("Loaded DB");
          project = doc.data();
          return { "data": "to send to the client" };
    }

Note that the promise chain is being returned, and the promise itself resolves to an object to send to the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM