Yii Framework Forum: Фоновая Рассылка Писем - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Фоновая Рассылка Писем Rate Topic: -----

#1 User is offline   h0ckeypl4yer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 14-October 12

Posted 09 April 2013 - 05:16 PM

Есть компании и клиенты. Клиент создает заявку и уведомление должно отправиться всем компаниям. Т.к. компаний много, то надо выполнять это в фоновом режиме. Как это реализовать на yii?

Как я понял можно создать некую команду в Yii и с помощью Cron ее запускать. Но как это сделать прямо из php скрипта? Командой exec? Чтобы в контроллере при обработке заявки и добавлении ее в базу автоматически запускался скрипт рассылки. Или я вообще не в том направлении думаю?
0

#2 User is offline   Charger 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 317
  • Joined: 03-September 11

Posted 10 April 2013 - 12:47 AM

Что бы создать консольную команду, которую можно будет запустить кроном, достаточно создать файлик в "protected\commands\" по инструкции Команда консоли
Если вы запустите эту команду в контроллере через exec, то возможно контроллер будет ждать пока она завершится и весь смысл потеряется. Хотя могу ошибаться, т.к. никогда такое не делал.
Для рассылок я обычно отвожу отдельную табличку или ключ в редисе - очередь. Приложение добавляет в эту очередь задания, а консольная команда обрабатывает эту очередь отправляя сообщения. Т.е. консольная команда запускается каждую минуту, если очередь сообщений не пустая, то начинает их отправлять. Может такая схема подойдет и вам, или кто то предложит более удобную.
Обращаю внимание, что необходимо будет предусмотреть защиту от запуска двух консольных команд. Что если команда не успеет отправить все сообщения за минуту и запустится еще одна? Ни в коем случае не должно произойти повторная отправка, поэтому получив адрес отправителя из очереди, нужно немедленно его удалить из неё, или поместить как обработанного.

Когда скорость обработки очереди важна, можно сделать в консольной команде бесконечный цикл: выбрал всю очередь, заснул на 2с, потом еще проверил пуста ли очередь и опять 2с ожидания. Но тогда нужно делать флаги, что бы если работает одна такая команда, вторая при запуске это определяла и тут же завершалась.
0

#3 User is offline   h0ckeypl4yer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 14-October 12

Posted 10 April 2013 - 07:03 AM

Да про создание читал. Там вроде есть такой прием как ignore_user_abort для exec, позволяет выполнять команду в фоне.
Если выполняется одна команда то следующую уже не запустить? Или может параллельно выполняться одна и та же команда несколькики экземплярами. Например если у меня одновременно создадут две заявки, будет вызов двух таких команд, не перекроют ли они одна другую?

По схеме через очередь. А можно же наверно делать так чтобы эта команда проверяла очередь не только каждую минуту но и по какому нибудь сигналу?
И еще вопрос как сделать запуск такой команды каждую минуту? Как контролировать ее работу(вдруг там проблемы с сервером хостинга или еще что-то)? С консольными командами в применении к сайтам просто никогда не работал, поэтому возникают такие вопросы.
0

#4 User is offline   Charger 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 317
  • Joined: 03-September 11

Posted 10 April 2013 - 07:17 AM

Quote

Там вроде есть такой прием как ignore_user_abort для exec, позволяет выполнять команду в фоне.

Тогда запускайте через exec и не беспокойтесь особо про очередь.

Quote

Если выполняется одна команда то следующую уже не запустить?

Почему нет? Консольная команда это процесс РНР которому выполняет определенный php файл. Главное что бы этот скрипт был потокобезопасным. У вас он наверное такое и получится, но все же приведу пример, что бы понимали чего следует избегать.
Например есть в таблице 100 записей с адресами и консольная команда отправляет каждому email и когда всем отправит- удаляет записи из таблицы. Если запустить вторую команду, когда первая уже разослала половине адресатов но еще не удалила, то вторая команда вычитает 100 адресов и начнет рассылать, в итоге всем уйдет по 2 сообщения.

Quote

И еще вопрос как сделать запуск такой команды каждую минуту?

Команда запускается просто, входите в папку protected и запускаете yiic <имя команды>
cd /projects/my_app/protected & yiic MyConsoleApp

можете настроить cron что бы запускал эту программу каждую минуту к примеру (чаще минуты cron не в состоянии)

Quote

А можно же наверно делать так чтобы эта команда проверяла очередь не только каждую минуту но и по какому нибудь сигналу?

В такой постановке вопроса, ничего не могу ответить.

Quote

Как контролировать ее работу(вдруг там проблемы с сервером хостинга или еще что-то)?

Очевидно только через лог. Пишите лог в своей команде (Журналирование Yii) а потом смотрите лог.
Cron еще отсылает админу на мыло то, что возвращает запущенные им команды (не знаю, по дефолту это или настраивать надо), но на моем проекте это было настроено, я тогда писал хелпер, что бы сообщение выводилось в консоль (а значит потом отправлялось кроном на мыло) и в журнал Yii
0

#5 User is offline   h0ckeypl4yer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 14-October 12

Posted 10 April 2013 - 07:18 AM

Да и надо паузу между появлением заявки на сайте и отправкой цепочки писем сделать минимальной, потому что скорость реакции на появление заявки очень важна. Именно поэтому и возникала мысль запуска прямо из контроллера
0

#6 User is offline   Charger 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 317
  • Joined: 03-September 11

Posted 10 April 2013 - 07:22 AM

Значит запускайте из контроллера.
0

#7 User is offline   h0ckeypl4yer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 14-October 12

Posted 10 April 2013 - 07:23 AM

Я хочу сделать чтобы каждая такая команда выполняла рассылку по определенной заявке, id которой передается команде в качестве аргумента. Команда уже и базы достает email по которым нужно сделать рассылку и в цикле выполняет эту рассылку. Тут я думаю описанной вами проблемы не возникнет.
0

#8 User is offline   KosmoBoy 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 23-October 12
  • Location:Kiev, Ukraine

Posted 11 April 2013 - 05:27 PM

View Posth0ckeypl4yer, on 10 April 2013 - 07:23 AM, said:

Я хочу сделать чтобы каждая такая команда выполняла рассылку по определенной заявке, id которой передается команде в качестве аргумента. Команда уже и базы достает email по которым нужно сделать рассылку и в цикле выполняет эту рассылку. Тут я думаю описанной вами проблемы не возникнет. Posted Image

Как по мне, то вы уже немного запутали. Понятно, что из БД достаёт! Но в каком цикле?
0

#9 User is offline   h0ckeypl4yer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 14-October 12

Posted 12 April 2013 - 01:39 PM

View PostKosmoBoy, on 11 April 2013 - 05:27 PM, said:

Как по мне, то вы уже немного запутали. Понятно, что из БД достаёт! Но в каком цикле?

А как я буду делать рассылку письма на несколько адресов в таком варианте?
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users