How to configure Amazon queue service consuming count












0














I've been coding some mass mailing script. It's working like this.

1. Pull users from database who must receive email. Currently this count is ~11k.

2. Put their email address in Amazon queue service.

3. Trigger another Lambda code which pulls from queue service, with interval.

4. Find each user's related products and build html template (Amazon s3) for mailing.

5. Send them with Amazon SES.



Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.



Current code snippet:



module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});

app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};

function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);

find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}


Error message:



2018-11-21T01:51:11.039Z    daf6727a-ed2f-11e8-9330-c581beef6958    { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }









share|improve this question






















  • Can’t you just limit the max concurrency of your lambda function?
    – Matthew Pope
    Nov 21 at 2:46










  • When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
    – John Rotenstein
    Nov 21 at 3:58










  • It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
    – Gereltod
    Nov 21 at 4:17


















0














I've been coding some mass mailing script. It's working like this.

1. Pull users from database who must receive email. Currently this count is ~11k.

2. Put their email address in Amazon queue service.

3. Trigger another Lambda code which pulls from queue service, with interval.

4. Find each user's related products and build html template (Amazon s3) for mailing.

5. Send them with Amazon SES.



Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.



Current code snippet:



module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});

app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};

function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);

find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}


Error message:



2018-11-21T01:51:11.039Z    daf6727a-ed2f-11e8-9330-c581beef6958    { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }









share|improve this question






















  • Can’t you just limit the max concurrency of your lambda function?
    – Matthew Pope
    Nov 21 at 2:46










  • When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
    – John Rotenstein
    Nov 21 at 3:58










  • It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
    – Gereltod
    Nov 21 at 4:17
















0












0








0







I've been coding some mass mailing script. It's working like this.

1. Pull users from database who must receive email. Currently this count is ~11k.

2. Put their email address in Amazon queue service.

3. Trigger another Lambda code which pulls from queue service, with interval.

4. Find each user's related products and build html template (Amazon s3) for mailing.

5. Send them with Amazon SES.



Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.



Current code snippet:



module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});

app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};

function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);

find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}


Error message:



2018-11-21T01:51:11.039Z    daf6727a-ed2f-11e8-9330-c581beef6958    { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }









share|improve this question













I've been coding some mass mailing script. It's working like this.

1. Pull users from database who must receive email. Currently this count is ~11k.

2. Put their email address in Amazon queue service.

3. Trigger another Lambda code which pulls from queue service, with interval.

4. Find each user's related products and build html template (Amazon s3) for mailing.

5. Send them with Amazon SES.



Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.



Current code snippet:



module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});

app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};

function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);

find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}


Error message:



2018-11-21T01:51:11.039Z    daf6727a-ed2f-11e8-9330-c581beef6958    { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }






amazon-web-services npm aws-lambda amazon-sqs amazon-ses






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 at 2:17









Gereltod

87761633




87761633












  • Can’t you just limit the max concurrency of your lambda function?
    – Matthew Pope
    Nov 21 at 2:46










  • When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
    – John Rotenstein
    Nov 21 at 3:58










  • It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
    – Gereltod
    Nov 21 at 4:17




















  • Can’t you just limit the max concurrency of your lambda function?
    – Matthew Pope
    Nov 21 at 2:46










  • When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
    – John Rotenstein
    Nov 21 at 3:58










  • It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
    – Gereltod
    Nov 21 at 4:17


















Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 at 2:46




Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 at 2:46












When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 at 3:58




When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 at 3:58












It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
– Gereltod
Nov 21 at 4:17






It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see module.exports.mail_puller it's pulling code which is working not intentional way.
– Gereltod
Nov 21 at 4:17














1 Answer
1






active

oldest

votes


















0














Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.



You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email calls to reduce SES throttling.



Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404430%2fhow-to-configure-amazon-queue-service-consuming-count%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.



    You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email calls to reduce SES throttling.



    Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.






    share|improve this answer


























      0














      Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.



      You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email calls to reduce SES throttling.



      Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.






      share|improve this answer
























        0












        0








        0






        Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.



        You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email calls to reduce SES throttling.



        Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.






        share|improve this answer












        Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.



        You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email calls to reduce SES throttling.



        Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 at 0:28









        Krease

        11.3k74059




        11.3k74059






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404430%2fhow-to-configure-amazon-queue-service-consuming-count%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'