Java: как отправлять x писем в минуту - PullRequest
3 голосов
/ 27 апреля 2020

Мне нужно отправить настроенное электронное письмо 400 клиентам.
Я делаю это:

for (Client c : clients){
  setUpEmail(c);
  sendMail(c);
}

Моя проблема заключается в том, что мой поставщик электронной почты разрешает мне отправлять только 10 электронных писем в минуту. Как я мог сделать это в l oop? Спасибо.

Ответы [ 3 ]

1 голос
/ 27 апреля 2020

Используйте Guava's RateLimiter.

Если у вас уже есть Guava в вашем пути к библиотеке, или если вы заинтересованы в ее добавлении, вы можете использовать это решение:

RateLimiter rateLimiter = RateLimiter.create(10/60d); // 10 permits per 60 seconds.
for (Client c : clients){
  setUpEmail(c);
  rateLimiter.acquire(1);
  sendMail(c);
}

Ваша проблема именно поэтому и была создана RateLimiter.

0 голосов
/ 27 апреля 2020
Deque clientsDeque = new ArrayDeque(clients);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () => {
   for (int i=0; i<10; i++){
     Client c = clientsDeque.poll();
     setUpEmail(c);
     sendMail(c);
   }
}
executor.schedule(task, 60, TimeUnit.SECONDS);
0 голосов
/ 27 апреля 2020

Используйте счетчик и подождите минуту, когда было отправлено десять писем:

int counter = 0; 
for (Client c : clients){
  counter++;      
  setUpEmail(c);
  sendMail(c);
  if(counter%10==0){
    Thread.sleep(60*1000); // wait a minute
  }
}

Это не идеально, поскольку вы можете потерять некоторое время, например, если отправке десяти писем требуется 20 секунд, вы можете только ждать За 40 секунд до начала нового массива.

Другой вариант - подождать между каждой почтой, чтобы время для 10 писем было не менее 60 секунд:

for (Client c : clients){     
  setUpEmail(c);
  sendMail(c);
  Thread.sleep(6*1000); // wait 6 seconds
}

И более сложное. :

int counter = 0; 
long start = System.currentTimeMillis();
for (Client c : clients){
  counter++;      
  setUpEmail(c);
  sendMail(c);
  if(counter%10==0){
    long needed = System.currentTimeMillis() - start;  // ms needed for ten mails
    Thread.sleep(60*1000 - needed); // wait rest of the minute
    start = System.currentTimeMillis(); // start of the next bulk
  }
}
...