写入S3(aws-sdk nodeJS)是否与存储桶中的列表对象冲突?

时间:2017-10-03 20:54:45

标签: node.js amazon-web-services amazon-s3

请记住,我最多可以被描述为节点和亚马逊S3的新秀。我有一些应用程序在后台写入S3。我想在写入文件时从S3读取,并且只在写入文件后读取。我尝试检查对象的数量并返回结果:

function haveFilesBeenWrittenToBucket(bucketName, callback) {
s3.listObjects({ Bucket: bucketName }, function(err, data) {
    const items = data.Contents;
    callback(items);
});

}

和readFile函数:

OSClient.prototype.readFile = function(params, callback) {
haveFilesBeenWrittenToBucket(params.Bucket, items => {
    console.log("Number of items " + items.length);
        if (items.length > 0) {
            const rl = readline.createInterface({
                input: s3.getObject(params).createReadStream()
            });
            const myArray = [];
            rl.on("line", function (line) {
                const lineArray = line.split(",");
                for (const value of lineArray) {
                    if (isNaN(value)) {
                        // line.split creates string elements, adding extraneous quotation marks in a string and converting
                        // number to string, so there is a need to reverse this process.
                        const slicedElement = value.slice(1, -1);
                        myArray.push(slicedElement);
                    } else {
                        const valueOfNumber = Number(value);
                        myArray.push(valueOfNumber);
                    }
                }
            })
                .on("close", function () {
                    callback(myArray);

                });
        }
         else{
                var myfunction = this.readFile.bind(this, params, callback);
                setTimeout(myfunction, 5000);
            }


    });

};

最后:

     targetClient.readFile(params, function (arrayResult) {
                            logger.info("Read file:" + fileName + OS_FILE_SUFFIX);
                            readArray = arrayResult;
                        });

如果我在回调(项目)上放置一个断点(在'haveFilesBeenWrittenToBucket'中)一切正常,我收回了桶中写的文件,但如果没有,似乎没有任何东西写入S3。看起来像一些竞争条件,但我真的很无能,我真的很感激一些帮助。列出对象和写入S3之间是否存在冲突(至少在很久以后,在其他测试中,当它不应该是(它是mocha测试套件的一部分时 - readFile在async.waterfall中)。已经有好几天没事了。正如我所说,这是我第一次接触节点,所以请耐心等待我。谢谢。

2 个答案:

答案 0 :(得分:1)

S3在读取后为列表提供最终一致性。所以,你可能会观察以下内容:

  

进程将新对象写入Amazon S3并立即列出其存储桶中的密钥。在完全传播更改之前,对象可能不会出现在列表中。

S3提供即时一致性的唯一情况是新对象的PUTS的写后读(有一个小警告,记录here)。 更多详情请见S3 consistency model

以下示例说明如何使用async retry等待对象然后检索其内容(在此示例中假定为文本)。

var aws = require("aws-sdk");
var async = require("async");

var s3 = new aws.S3();
var bucket = 'mybucket';
var iteration = 0;

function waitForObjects(bucket, callback) {
    console.error(`Iteration: ${++iteration}`);

    s3.listObjects({Bucket:bucket}, function(err, data) {
        if (err) {
            callback(err);
        } else if (!data.Contents || !data.Contents.length) {
            callback(new Error("No objects"))
        } else {
            callback(null, data);
        }
    });
}

// Try calling waitForObjects 10 times with exponential backoff
// (intervals of 100, 200, 400, 800, 1600, ... milliseconds)
async.retry({
    times: 10,
    interval: function(retryCount) {
        return 50 * Math.pow(2, retryCount);
    }
}, async.apply(waitForObjects, bucket), function(err, data) {
    if (err) {
        console.error(`Error waitForObjects: ${err}`);
    } else {
        console.log(`Object count: ${data.Contents.length}`);

        data.Contents.forEach(function(item, index) {
            console.log(`Object ${index+1} key: ${item.Key}`);

            s3.getObject({Bucket:bucket, Key:item.Key}, function(err, data) {
                console.log(`Object ${index+1} txt: ${data.Body.toString()}`);
            });
        });
    }
});

答案 1 :(得分:1)

两件事。首先,事实证明我的问题与nodeJS无关。叹 其次,API现在提供了一个等待'用于轮询存储桶是否存在的方法:

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#waitFor-property