Skip to content

Instantly share code, notes, and snippets.

@davydovanton
Last active March 13, 2018 11:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davydovanton/14dbcd302ef8f74a5e4a916315c25e28 to your computer and use it in GitHub Desktop.
Save davydovanton/14dbcd302ef8f74a5e4a916315c25e28 to your computer and use it in GitHub Desktop.

ситуация, есть приложение, которое создает пользователя, а потом хочет сделать кучу разной работы в бэкграунде (послать данные пользователю, отправить аналитику в сегмент, сделать какие-то модели в БД, выкачать дамп данных, etc)

вариант первый, взять сайдкик:

class CreatedUserNotificationWorker
  # ...
end

class CreatedUserAnalyticsWorker
  # ...
end

...

а потом вызывать что-то в таком духе:

user = repository.create(attributes)

CreatedUserNotificationWorker.perform_async(user.id)
CreatedUserAnalyticsWorker.perform_async(user.id)
# ...

можно создать супервайзер, который сам будет спавнить воркеры

class CreatedUserSuperviserWorker
  def perform(payload)
    WORKERS.each { |worker| worker.perform_async(payload) }
  end
end

плюсы:

  1. сайдкик вылезан майком полностью, поэтому быстро ставится и быстро делается все
  2. все знают как это работает и объяснять не нужно, порог входа низкий

минусы:

  1. у тебя создается N сообщений в бд на событие, за этим сложно следить в реальной системе (много абстракций, за каждой по своему следить надо, потому что имя другое)
  2. редис, это как плюс (быстро и легко в поддержке), так и минус, потому что персистентность нулевая. если у тебя события важные (например биллинг какой-то), я бы не советовал юзать его + только в про версии сайдкиа есть вариант с нормальным завершением воркеров
  3. если ты хочешь взять не руби или дергать воркеры из проекта в проект (*аля сервисы) - придется соснуть, взять фактори или писать обвязку для того, что бы вызывать воркер из другого проекта

Есть другой вариант, можно взять что угодно (кафку, реббит, да хоть постгрес) и сделать subscribers на событие. пример вот тут https://github.com/davydovanton/hanami_event_example, посмотреть лучше https://github.com/davydovanton/hanami_event_example/blob/master/event_server.rb вот этот файл.

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

class NotificationHandler
  on 'user_created' do |payload|
    # code for sending sms and email to user
  end
end

class AnalyticsHandler
  on 'user_created' do |payload|
    # code for sending some events to analytics services
  end
end

class PrerareHandler
  on 'user_created' do |payload|
    # code for creatring some related things for user
  end
end

...

А потом просто создаешь событие, и каждый из хендлеров будет выполнять код под событие

плюсы:

  1. не прибито к языку или проекту. можешь писать хендлеры хоть на хаскеле и вызывать из 1-N сервисов
  2. персистентность выше, это автоматическое логгирование событий в системе
  3. нет кучи разных событй, есть просто куча хендлеров

минусы:

  1. дебажить сложно (асинхронно же) в реальных системах
  2. выше порог входа
  3. придется писать свою обвязку
  4. некоторые персистенс штуки дороги в поддержке (например та же кафка)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment