2. Большой проект
30 человек
4 года
330 000 строк кода
20 репозиториев
сложная предметная область
технические решения на границе экосистемы
Ruby
рядом аналитический стек на
Hadoop/Java/Python
2 / 20
3. Сложность предметной области
Управление спросом (Demand Response)
▶ N раз в год c XX:XX до YY:YY часов цены внезапно
повышаются
▶ события сгруппированы в программы
▶ уведомление людей
▶ уведомление устройств
Тарифный план
▶ энергия: 0 — 100 кВч, 100 — 400 кВч,…
▶ время: 8:00 — 12:00, 12:00 — 16:00,…
▶ мощность: 10 кВ, 20кВ,…
▶ пиковые часы: 12:00 — 14:00 послезавтра
▶ время действия: июнь — август
Развитие стандартов: 2.0 и 1.0 — это две
большие разницы
3 / 20
4. Rails — говно
Покрывает 95% случаев
Культура необразованных упорков
Мантры как мины
MVC не масштабируется
«Всё уже написано до нас»
4 / 20
5. Виджет — проблема
Автономный встраиваемый кусок
функциональности
Имеет независимый от «большой» страницы
поток управления
Плохо ложится на ReST и рельсовый MVC
Пример: создание и редактирование события
управления спросом
5 / 20
6. Виджет — решение
Apotomo: https://github.com/apotonick/apotomo
class ParentController ActionController::Base
has_widget do |root|
root widget(:event)
end
# ...
end
class EventWidget Apotomo::Widget
def new(args = {}); render; end
def edit(args = {}); render; end
def create(event); end # event — внутреннее для
Apotomo событие
end
# Внутри шаблона
= render_widget :event, :new
6 / 20
7. Event sourcing внутри приложения
Легкое горизонтальное масштабирование
Несколько действий на один сигнал
7 / 20
8. Базовое идеологическое про события
Что-то произошло ) что-то надо делать
Началось ) что-то надо делать
Закончилось ) что-то надо делать
На одно событие может быть 100500 действий
8 / 20
9. Event sourcing vs Resque
За Resque:
тот же «запустил и забыл»
та же легковесность запуска
то же масштабирование — воркеры можно
разнести по разным машинам
Против Resque:
один сигнал — одно действие
9 / 20
10. Общая шина сообщений
Можно использовать лучшее из обоих подходов:
очередь сообщений — для сообщений,
Resque — для действий.
10 / 20
11. Сообщения vs HTTP API
К рассмотрению:
Тяни или толкай
Объём даннных
Очевидно:
малый объём оповещения — сообщения
большой объём данных — стягиваем через HTTP
API
11 / 20
13. Observers
Против:
не входят в Rails 4
непрозрачны, слишком много магии
За:
SRP: шлём сообщения
Против:
есть выход и получше
13 / 20
14. Request/Operation
Уточнённый кусок DDD: Boundary и Service
https://github.com/apotonick/trailblazer:
Contract/Operation
Request — контракт:
▶ первичная валидация, что параметры ок
▶ удобство доступа к объектам предметной
области
▶ иммутабельный FormObject или ParameterObject
class EventsController::Create::Request
attr_reader :start_time
def initialize(params)
@device_uid = params[:device_uid]
@start_time = params[:start_time]
end
def device
@device ||= Device.find_by_uid(@device_uid)
end
end
14 / 20
15. Request/Operation
Operation — кусок бизнес-логики AKA Service
(DDD) AKA Command (CQRS).
В простейшем случае отвечает только на
идемпотентный вызов #success?
Есть проблема с пространством имён —
некрасиво
class EventsController
def create
operation = Create::Operation.new(Create::Request.
new(params))
if operation.success?
# ...
else
# ...
end
end
end
15 / 20
16. Ограниченные контексты и разные
языки
Главная система со своим сложившимся
лексиконом
Smart Energy Profile 2
OpenADR 2.0b
Разные языки — разные серверы
Антикоррупционный слой через HTTP API
▶ Хозяин и раб
▶ Адаптер на стороне хозяина: переименование и
комбинация
▶ Декоратор на стороне раба: сложно
▶ Срезаем углы: ActiveAdmin как JSON API
▶ Углы могут кусать: id vs uid
16 / 20
17. Разделение на гемы
Горизонтальное — по слоям — ок
Вертикальное — самоубийство
Связанные жизненные циклы — зло
Корпоративное пространство имён — ок, если
готовить правильно
Помни о близнецовой связи (connascence)
17 / 20
18. Кодерские мелочи
Декораторы убивают хелперы, и это хорошо
FormObjects вместо accepts_nested_attributes_for
Иммутабельность FTW
Щепотка ФП: #flat_map, #inject, #take
Если появляется QueryObject, что-то сдохло в
консерватории
Yardoc
18 / 20
19. Бог не фраер
Ибо очи Его над путями человека, и Он видит все
шаги его
Абстракции
Границы
Асинхронность
SOLID
Документация
Рациональность
19 / 20