请求正文有时为null

时间:2017-09-07 20:31:08

标签: node.js amazon-web-services asynchronous aws-lambda

当拉入lambda时,请求体有时(少于1%的时间)为null。我一次一个地处理14,000个请求机构的订单。任何错误的请求机构都必须手动处理。为什么身体随机变成空?

示例代码从prompt(节点索引)运行:

const async = require('async');
const _ = require('lodash');
const moment = require('moment');
const Client = require('node-rest-client').Client;
const fs = require('fs');

const input = require('./TestFull.json');

module.exports = () => {
    const filename = `./eventfulFails-${new moment().format("YYYY-MM-DD-HHmmss")}.json`;
    console.log('Start Time: ', new moment().format("HH:mm:ss"));

    let failedObjects = {
        events: [],
        venues: [],
        performers: []
    };

    async.parallel([
        async.apply(processVenues, input.venues, failedObjects),
        async.apply(processPerformers, input.performers, failedObjects)
    ], (lookupErr) => {
        if (lookupErr) {
            return console.error('Error processing venues and performers.', lookupErr);
        }
        console.log('Start Events: ', new moment().format("HH:mm:ss"));

        async.waterfall([
            async.apply(processEvents, input.events, failedObjects)
        ], (eventErr) => {
            if (eventErr) {
                console.log('Time of Failure: ', new moment().format("HH:mm:ss"));
                return console.error('Error processing events.', eventErr);
            }
            console.log('End Time: ', new moment().format("HH:mm:ss"));

            if (failedObjects.events.length || failedObjects.venues.length || failedObjects.performers.length) {
                const stream = fs.createWriteStream(filename);
                stream.once('open', function(fd) {
                    stream.write(JSON.stringify(failedObjects));
                    stream.end();
                });
            }
        });
    });
};

function processVenues(venues, failedObjects, callback) {
    const calls = [];

    for (let i = 0; i < venues.length; i++) {
        const v = venues[i];

        calls.push(async.apply((venue, postCallback) => {
            const client = new Client();
            const args = {
                data: venue,
                headers: {"Content-Type": "application/json"}
            };

            client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful-venue', args, (data, response) => {
                if (response.statusCode !== 200 && response.statusCode !== 201) {
                    failedObjects.venues.push({
                        venue,
                        response
                    });
                    console.log('venue status code: ', response);
                    console.log('venue data: ', venue);
                }
                return postCallback(null);
            });
        }, v));
    }

    async.waterfall(calls, callback);
}

function processPerformers(performers, failedObjects, callback) {
    const calls = [];

    for (let i = 0; i < performers.length; i++) {
        const v = performers[i];

        calls.push(async.apply((performer, postCallback) => {
            const client = new Client();
            const args = {
                data: performer,
                headers: {"Content-Type": "application/json"}
            };

            client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful-performer', args, (data, response) => {
                if (response.statusCode !== 200 && response.statusCode !== 201) {
                    failedObjects.performers.push({
                        performer,
                        response
                    });
                    console.log('performer status code: ', response);
                    console.log('performer data: ', performer);
                }
                return postCallback(null);
            });
        }, v));
    }

    async.waterfall(calls, callback);
}

function processEvents(events, failedObjects, callback) {
    const calls = [];

    for (let i = 0; i < events.length; i++) {
        const v = events[i];

        calls.push(async.apply((event, postCallback) => {
            const client = new Client();
            const args = {
                data: event,
                headers: {"Content-Type": "application/json"}
            };
            client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful', args, (data, response) => {
                if (response.statusCode !== 200 && response.statusCode !== 201) {
                    failedObjects.events.push({
                        event,
                        response
                    });
                    console.log('event status code: ', response);
                    console.log('event data: ', event);
                }
                return postCallback(null);
            });
        }, v));
    }

    async.waterfall(calls, callback);
}

if (!module.parent) {
    module.exports();
}

函数processVenues(eventful-venue-load)被称为:

const _ = require('lodash');
const AWS = require('aws-sdk');
const async = require('async');
const sdk = require('@consultwithmikellc/withify-sdk');

const host = process.env.aurora_host;
const user = process.env.aurora_user;
const database = process.env.aurora_database;
let decryptedPassword;

const lambda = new AWS.Lambda({
    region: 'us-west-2' //your region
});

class WithifyEventCreate extends sdk.Lambda {
    constructor(event, context, keysToDecrypt) {
        super(event, context, keysToDecrypt);

        this.getLocation = this.getLocation.bind(this);
        this.insertLocations = this.insertLocations.bind(this);
        this.insertLocationImages = this.insertLocationImages.bind(this);
    }

    decryptedKey(key, value) {
        switch (key) {
            case 'aurora_password':
                decryptedPassword = value;
                break;
        }
    }

    initializeComplete() {
        this.connect(host, user, decryptedPassword, database, true);
    }

    connectComplete() {
        async.waterfall(
            [
                this.getLocation,
                this.insertLocations,
                this.insertLocationImages
            ]
        );
    }

    getLocation(callback) {
        const {id: eventfulLocationID} = this.body;

        this.connection.query('SELECT * FROM `Location` WHERE `eventfulLocationID` = ?',
            [eventfulLocationID],
            (err, results) => {
                if (err) {
                    // error call block
                    return this.sendResponse(err, this.createResponse(500));
                } else if (results.length === 1) {
                    console.log('Invoking withify-eventful-venue-update...');
                    lambda.invoke({
                        FunctionName: 'withify-eventful-venue-update',
                        Payload: JSON.stringify(this.event)
                    }, (error, data) => {
                        return this.sendResponse(null, JSON.parse(data.Payload));
                    });
                } else if (results.length > 1) {
                    return this.sendResponse(`The location lookup produced multiple results. event:${JSON.stringify(this.body)}`, this.createResponse(500));
                } else {
                    return callback(null);
                }
            }
        );
    }

    insertLocations(callback) {
        const {name: locationName, address: street, city, region_abbr: state, postal_code,
            description, id: eventfulLocationID, latitude: lat, longitude: lng, withdrawn: locationWithdrawn} = this.body;
        let addresses = street.concat(', ', city, ', ', state, ', ', postal_code);

        if (!description.length){
            var phones = "";
        }else{
            var re = /(([\(][0-9]{3}[\)][\s][0-9]{3}[-][0-9]{4})|([0-9]{3}[-][0-9]{3}[-][0-9]{4})|([0-9]{3}[\.][0-9]{3}[\.][0-9]{4}))/i;
            this.body.found = description.match(re);

            if (!this.body.found){
                var phone = "";
            }else{
                if (!this.body.found.length){
                    var phone = "";
                }else{
                    var phone = this.body.found[0];
                }
            }
        }
        this.connection.query('INSERT IGNORE INTO `Location` (`locationName`, `address`, ' +
            '`phone`, `lat`, `lng`, `eventfulLocationID`, `locationWithdrawn`) VALUES (?, ?, ?, ?, ?, ?, ?)',
            [locationName, addresses, phone, lat, lng, eventfulLocationID, locationWithdrawn],
            (err, results) => {
                if (err) {
                    return this.sendResponse(err, this.createResponse(500));
                }

                this.body.locationID = results.insertId;
                return callback(null);
            }
        );
    }

    insertLocationImages(callback) {
        var altText = "";
        const images = _.flatten(this.body.images.map(im => {
            return _.map(im.sizes, (ims, idx) => {
                const title = `Image ${idx}`;

                return [
                    this.body.locationID,
                    this.body.name,
                    ims.url,
                    null,
                    null,
                    this.body.id,
                    ims.width,
                    ims.height
                ];
            });
        }));
        if(!images[0]){
            return this.sendResponse(null, this.createResponse(201, this.body));
        }
        this.connection.query('INSERT IGNORE INTO `LocationImage` (`locationID`, `imageTitle`, `imageUrl`, ' +
            '`imageName`, `altText`, `eventfulLocationID`, `width`, `height`) VALUES ?',
            [images],
            (err, results) => {
                if (err) {
                    return this.sendResponse(err, this.createResponse(500));
                } else if (results.affectedRows !== images.length) {
                    return this.sendResponse('The image inserts did not affect the right number' +
                        ' of rows.', this.createResponse(500));
                }

                return this.sendResponse(null, this.createResponse(201, this.body));
            }
        );
    }
}

exports.handler = (event, context) => {
    const withifyEventCreate = new WithifyEventCreate(event, context, ['aurora_password']);
    withifyEventCreate.initialize([decryptedPassword]);
};

0 个答案:

没有答案