简体   繁体   中英

Meteor.call calls method >100 times with one button click

Our team has a production-level Meteor app. In the app we have a particular Meteor method which sends an email. Today it sent 127 emails from one click of the Submit button (over the course of about 20 minutes).

I cannot post the exact code but the basic flow is pretty straightforward:

  1. We catch the submit event and send everything to the server via Meteor.call
  2. The Meteor method sends a request to a service to render a PDF
  3. The Meteor method sends a request to SendGrid with the attachments and other email data
  4. The Meteor method returns and triggers the callback

We don't really have much basis for determining the exact problem and are researching but are suspecting it is partly due to the end user's connection timing out and Meteor re-sending requests for which it did not get any response.

There are two threads we found related to the problem: https://groups.google.com/forum/#!topic/meteor-talk/vu5kk3t0Lr4 and https://github.com/meteor/meteor/issues/1285

Which both answer that methods should be idempotent. Obviously sending an email directly from a method is not idempotent so we proposed that the Meteor method should add these emails to a queue and have a different service process the queue on a schedule. However, we do not want to start implementing solutions that might help solve the problem.

So, this leaves me with two questions:

  • What exactly would cause a Meteor method to be called 127 times? How do we prevent this from happening? Is this a bug in Meteor or a bug in our app?
  • If we update the method so it uses EmailQueue.insert(...) (and let something else process the queue) does that just mean we, in this case, would put 127 records into the queue instead? Is the only solution here having some sort of lock to ensure duplicate records are not processed/inserted?

Thank you for any insight.

I would recommend you post the code, the process may be simple but there's usually small subleties that can help determine what's going on, ie is it async/is there anything that may be blocking.

What may cause it

If Meteor doesn't respond to your browser it thinks it has not yet fired the call and it re-calls it. At least this is what I can gather may be happening using the information you've provided.

To get passed this ensure that

  1. When sending the email you either use this.unblock ( http://docs.meteor.com/#method_unblock ) or use asynchronous JS with any of the proccesses you're doing
  2. Ensure that nothing happening is blocking the main thread for your app. (It's hard to tell what it could be without any code)
  3. Errors. If meteor restarts and reconnects it will prompt the browser to re-send the Meteor.call

The big clue here is that it took 20 mins, so its very likely to any of these.

How to check. Check the Network tab in your browser to see what's being sent to the server. Is the method being called multiple times? Are there re-connection attempts?

To answer the second question on whether using an Email Queue would help, it may not, it depends more on what's causing the initial problem.

Additionally: I think SendGrid automatically queues the emails anyway so you could send them all the emails at once and they queue them so they send out depending on your limits with them. (Not sure on this since I used them quite a while back)

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