简体   繁体   English

计时器触发了Azure功能的开始但没有结束?

[英]Timer triggered Azure Function starting but not ending?

I want to use a timer triggered Azure Function to generate a number of axios post-calls to change the throughput setting of a number of CosmosDB collections. 我想使用计时器触发的Azure函数来生成许多axios调用,以更改多个CosmosDB集合的吞吐量设置。

According to the logs the below code will start (ie a "[ Info] Function started " message appears), but then no more logging will appear and the function will end with status code 202 Accepted . 根据日志,下面的代码将开始(即,出现“ [ Info]函数已启动 ”消息),但是将不再显示日志,并且该函数将以状态代码202 Accepted结束。

I have a suspicion the problem is caused by the way I handle the axios promises, but after many attempts I am turning to Stackoverflow for help. 我怀疑这个问题是由我处理axios承诺的方式引起的,但是经过多次尝试,我还是向Stackoverflow寻求帮助。

Any help would be greatly appreciated. 任何帮助将不胜感激。

const axios = require("axios");
const azure = require("azure-storage");
const functionURL = "https://<redacted>.azurewebsites.net/api/ChangeRU?code=<redacted>"

// Update Offer for Collection
function updateOffer_for_Collection_RESTCall(
    environment,
    database,
    collection,
    newRU
) {
    context.log(`\nUpdate throughput for collection (${collection}) in database (${database}) of environment (${environment}) to: ${newRU}`);

    // Execute REST call
    const url = functionURL + "&env=" + environment + "&database=" + database + "&collection=" + collection + "&ru=" + newRU;
    context.log(`url = ${url}`);

    return url;
}

module.exports = function (context, myTimer) {
    var timeStamp = new Date().toISOString();
    context.log('Scale down job started:', timeStamp);

    if (myTimer.isPastDue) {
        context.log('Scale down job is running late!');
    }

    var collectionTableService = azure.createTableService("<storageaccount>", "<redacted>");

    const query = new azure.TableQuery()
        .top(2)
        .where('PartitionKey eq ?', 'DBCollections');
    context.log('Query created...');

    collectionTableService.queryEntities('DBCollections', query, null, function (error, result, response) {
        if (!error) {
            // result.entries contains entities matching the query
            const collections = result.entries;
            let axiosArray = [];
            for (let collection of collections) {
                context.log("Collection: " + JSON.stringify(collection) + "\n");
                // Process collection
                let url = updateOffer_for_Collection_RESTCall(collection.environment._, collection.database._, collection.collection._, 400);
                let newPromise = axios({
                    method: 'post',
                    url: url,
                    data: {}
                });
                axiosArray.push(newPromise);
            };

            axios
                .all(axiosArray)
                .then(
                function (results) {
                    let temp = results.map(r => r.data);
                    context.log('submitted all axios calls');
                })
                .catch(error => { });
            context.done();
        } else {
            context.log('Error retrieving records from table DBCollections: ' + error);
            context.done();
        }
    });
};

Having acquired a better understanding of Javascript Promises in the last few days, I am ready to answer my own question :-) 在最近几天对Javascript承诺有了更好的了解之后,我准备回答我自己的问题:-)

Consider the following rewrite: 考虑以下重写:

// This Azure Function will change the request units setting of a number of Cosmos DB database collections at CSP <redacted>

// Use https://github.com/axios/axios as a REST client
const axios = require("axios");
const azure = require("azure-storage");
const functionURL =
    "https://<redacted>.azurewebsites.net/api/<redacted>?code=<redacted>";


module.exports = function (context, myTimer) {
    context.log("Going in...");

    function asyncPostURL(url) {
        return new Promise((resolve, reject) => {
            axios.post(url)
                .then(function (response) {
                    context.log(`POST response: status=${response.status}, data=${response.data}`);
                    resolve(response.data);
                })
                .catch(function (error) {
                    context.log(error);
                    reject(error);
                });
        });
    }


    // Create POST url  to update offer for collection
    function create_url(record) {
        const environment = record.environment._;
        const database = record.database._;
        const collection = record.collection._;
        const newRU = record.scaleupRU._;

        context.log(
            `\nUpdate throughput for collection (${collection}) in database (${database}) of environment (${environment}) to: ${newRU}`
        );

        // Create POST url
        const url =
            functionURL +
            "&env=" +
            environment +
            "&database=" +
            database +
            "&collection=" +
            collection +
            "&ru=" +
            newRU;
        context.log(`url: ${url}`);

        return url;
    }

    function post_urls(arr, final, context) {
        return arr.reduce((promise, record) => {
            return promise
                .then(result => {
                    let url = create_url(record);
                    context.log(`url: ${url}.`);
                    return asyncPostURL(url).then(result => final.push(result));
                })
                .catch(error => {
                    context.log(error);
                });
        }, Promise.resolve());
    }


    var timeStamp = new Date().toISOString();
    context.log("Scale down job started:", timeStamp);

    if (myTimer.isPastDue) {
        context.log("Scale down job is running late!");
    }

    var collectionTableService = azure.createTableService(
        "pbscsptoolsstorage",
        "<redacted>"
    );

    const query = new azure.TableQuery()
        //.top(2)
        .where("PartitionKey eq ?", "DBCollections");
    context.log("Query created...");

    const get_collections = tbl =>
        new Promise((resolve, reject) => {
            collectionTableService.queryEntities(tbl, query, null, function (
                error,
                result,
                response
            ) {
                if (!error) {
                    context.log(`# entries: ${result.entries.length}`);
                    resolve(result.entries);
                } else {
                    reject(error);
                }
            });
        });

    var final = [];
    get_collections("<redacted>").then(
        collections => {
            context.log(`# collections: ${collections.length}`);
            post_urls(collections, final, context).then(() => context.log(`FINAL RESULT is ${final}`))
                .then(() => context.done());
        },
        error => {
            context.log("Promise get_collections failed: ", error)
                .then(() => context.done());
        }
    )

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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