Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

20
Несоциалочка на рельсах Сергей Укустов Провектус, Казань 2014-09-20 Web Expert Day 1 / 20

Transcript of Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Page 1: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Несоциалочка на рельсах

Сергей Укустов

Провектус, Казань

2014-09-20Web Expert Day

1 / 20

Page 2: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Большой проект

• 30 человек• 4 года• ≥ 330 000 строк кода• ≥ 20 репозиториев• сложная предметная область• технические решения на границе экосистемыRuby

• рядом аналитический стек наHadoop/Java/Python

2 / 20

Page 3: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Сложность предметной области

• Управление спросом (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

Page 4: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Rails — говно

• Покрывает 95% случаев• Культура необразованных упорков• Мантры как мины• MVC не масштабируется• «Всё уже написано до нас»

4 / 20

Page 5: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Виджет — проблема• Автономный встраиваемый кусокфункциональности

• Имеет независимый от «большой» страницыпоток управления

• Плохо ложится на ReST и рельсовый MVC• Пример: создание и редактирование событияуправления спросом

5 / 20

Page 6: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Виджет — решениеApotomo: https://github.com/apotonick/apotomoclass ParentController < ActionController::Basehas_widget do |root|root << widget(:event)end# ...

end

class EventWidget < Apotomo::Widgetdef new(args = {}); render; enddef edit(args = {}); render; enddef create(event); end # event — внутреннее дляApotomo событие

end

# Внутри шаблона= render_widget :event, :new

6 / 20

Page 7: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Event sourcing внутри приложения• Легкое горизонтальное масштабирование• Несколько действий на один сигнал

7 / 20

Page 8: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Базовое идеологическое про события

• Что-то произошло ⇒ что-то надо делать• Началось ⇒ что-то надо делать• Закончилось ⇒ что-то надо делать• На одно событие может быть 100500 действий

8 / 20

Page 9: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Event sourcing vs Resque

За Resque:• тот же «запустил и забыл»• та же легковесность запуска• то же масштабирование — воркеры можноразнести по разным машинам

Против Resque:• один сигнал — одно действие

9 / 20

Page 10: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Общая шина сообщенийМожно использовать лучшее из обоих подходов:

• очередь сообщений — для сообщений,• Resque — для действий.

10 / 20

Page 11: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Сообщения vs HTTP APIК рассмотрению:

• Тяни или толкай• Объём даннных

Очевидно:• малый объём оповещения — сообщения• большой объём данных — стягиваем через HTTPAPI

11 / 20

Page 12: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

EventMachine vs Resque

12 / 20

Page 13: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Observers

Против:• не входят в Rails 4• непрозрачны, слишком много магии

За:• SRP: шлём сообщения

Против:• есть выход и получше

13 / 20

Page 14: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Request/Operation• Уточнённый кусок DDD: Boundary и Service• https://github.com/apotonick/trailblazer:Contract/Operation

• Request — контракт:▶ первичная валидация, что параметры ок▶ удобство доступа к объектам предметнойобласти

▶ иммутабельный FormObject или ParameterObjectclass EventsController::Create::Requestattr_reader :start_timedef initialize(params)@device_uid = params[:device_uid]@start_time = params[:start_time]

enddef device@device ||= Device.find_by_uid(@device_uid)

endend

14 / 20

Page 15: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Request/Operation• Operation — кусок бизнес-логики AKA Service(DDD) AKA Command (CQRS).

• В простейшем случае отвечает только наидемпотентный вызов #success?

• Есть проблема с пространством имён —некрасиво

class EventsControllerdef createoperation = Create::Operation.new(Create::Request.new(params))if operation.success?# ...

else# ...

endend

end

15 / 20

Page 16: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Ограниченные контексты и разныеязыки

• Главная система со своим сложившимсялексиконом

• Smart Energy Profile 2• OpenADR 2.0b• Разные языки — разные серверы• Антикоррупционный слой через HTTP API

▶ Хозяин и раб▶ Адаптер на стороне хозяина: переименование икомбинация

▶ Декоратор на стороне раба: сложно▶ Срезаем углы: ActiveAdmin как JSON API▶ Углы могут кусать: id vs uid

16 / 20

Page 17: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Разделение на гемы

• Горизонтальное — по слоям — ок• Вертикальное — самоубийство• Связанные жизненные циклы — зло• Корпоративное пространство имён — ок, еслиготовить правильно

• Помни о близнецовой связи (connascence)

17 / 20

Page 18: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Кодерские мелочи

• Декораторы убивают хелперы, и это хорошо• FormObjects вместо accepts_nested_attributes_for• Иммутабельность FTW• Щепотка ФП: #flat_map, #inject, #take• Если появляется QueryObject, что-то сдохло вконсерватории

• Yardoc

18 / 20

Page 19: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Бог не фраер

Ибо очи Его над путями человека, и Он видит всешаги его

• Абстракции• Границы• Асинхронность• SOLID• Документация• Рациональность

19 / 20

Page 20: Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"

Вопросы?

20 / 20