2017-02-23 61 views
0

У меня есть приложение Rails, где я должен добавить миллионы поздних платежей за счета-фактуры, которые подлежат оплате.Как запустить пакетное задание одновременно с обновлениями записей?

В настоящее время у меня есть задание Que, которое выполняется один раз в день и выбирает партии счетов-фактур с использованием .find_in_batches(batch_size: 100). Я пометил другие общие библиотеки заданий, так как я уверен, что одна и та же проблема переносится. Обратите внимание, однако, что Que поддерживается базой данных, а не при поддержке Redis.

Проблема в том, что именно в этот момент клиент может оплатить свой счет, а поздняя плата будет добавлена ​​в оплаченный счет.

Я не уверен, как смириться с этой разницей исполнительским образом (или любым способом, если быть честным).

Я буду делать это для миллионов строк, поэтому метод должен быть быстрым.

Каковы различные стратегии для этого?

+0

'create_late_fee_for (invoice), если только invoice.paid?' –

+1

Альтернативно ... есть другой процесс, который запускается сразу же после этого, и ищет поздние платежи, созданные после 'invoice.paid_at' date ... и удаляющие поздние версии, если это произошло. –

+0

Можем ли мы увидеть еще немного кода? – Sean

ответ

0

Я думаю, вы уже наметили противоречие. Вы хотите сделать что-то общее, связанное с исполнителем, а ваша очередь - в базе данных.

Я сделал нечто подобное, и у меня был большой опыт использования Sidekiq. У меня была бы первая работа .find_in_batches(...) и использовать ее для планирования каждого просроченного счета-фактуры в качестве отдельного задания.

Когда задание выполняется, ему необходимо перепроверить, если счет был оплачен, прежде чем добавлять плату.

Использование sidekiq для этого, каждый процесс sidekiq по умолчанию будет иметь 25 рабочих, что значительно улучшит производительность. Вы можете точно настроить это и увеличить количество процессов sidekiq по мере необходимости. Scaling sidekiq - это действительно удовольствие! Обратите внимание, что соединения с базой данных могут стать узкой точкой.