RUBY ON RAILS W DUŻYM PROJEKCIE

Czy to ma sens?

Tomasz Warkocki

O MNIE

  • Pracuję w Ruby i Ruby on Rails od 8 lat
  • Byłem programistą i team leaderem w software house
  • Obecnie jestem programistą i CTO w Fieldly.com
  • Lubię: Big Data, Lego Mindstorms i Arduino

o czym porozmawiamy

  • Wady i zalety Ruby on Rails
  • Najczęstsze problemy i dobre praktyki
  • Wydajność Ruby on Rails
  • Rynek pracy i przyszłość Ruby on Rails

ruby on rails

Ruby on rails

  • Ruby -  Yukihiro "Matz" Matsumoto (1995)
  • Convention over Configuration (CoC) 
  • Don't repeat yourself (DRY)
  • Generatory (scaffolding)
  • Łatwe tworzenie API (mobile, ajax, Rails 5)
  • Gemy do wszystkiego
  • Model View Controller (MVC)
  • "Fat models, skinny controllers" - srsly?!
  • REST
  • ActiveRecord (magia, callbacki, Arel)

Wciąż popularny framework

  • Twitter
  • Airbnb
  • Hulu
  • Shopify
  • Basecamp
  • GitHub
  • Styczeń 2016 - 1.200.000 stron internetowych w RoR

Jak to zwykle bywa...

  • Mały "projekcik"
  • Kilka modeli
  • Jeden model główny
  • Testy dodamy później...
  • Przecież to tylko MVP
  • Biznes goni z feature'ami

Jak to zwykle bywa...

  • User Stories  tworzone na kolanie
  • Brak jakiegoś spójnego workflow
  • Team złożony z samych juniorów
  • Ooo! Mamy już 40 modeli? Jak to!?
  • Praktycznie nie jesteśmy w stanie wprowadzać więcej zmian
  • Częsty scenariusz... inna ekipa i przepisanie od zera :(

dobre praktyki

Właściwy workflow

  • Agile - SCRUM (retrospekcje i gotowość na zmiany)
  • Zarządzanie zadaniami (JIRA, Pivotal Tracker, Trello)
  • Zarządzanie wersjami
  • Testowanie (RSpec, Cucumber, TTD, BDD)
  • Continuous Integration (Jenkins, CodeShip)
  • Git flow
  • Static Code Analysis (Rubocop, CodeClimate)

Właściwy workflow

  • Code Review (GitHub)
  • Code maintenance (Technical Debt, refaktoryzacja)
  • Easy deployment (DevOps services, Heroku, Cloud66)
  • Automatyczne wykrywanie wyjątków (BugSnag, NewRelic)
  • Monitorowanie wydajności (NewRelic)
  • Łatwe debugowanie i  przeglądanie logów (LogEntries)

Problemy w kodzie

  • Zduplikowany kod
  • Ogromne klasy (God Class)
  • Ogromne metody
  • Bałagan w nazwach klas, metod, zmiennych
  • Spaghetti code

Problemy w kodzie

  • Nadużywanie callback'ów
  • Długie listy parametrów metod
  • Mixin'y w Ruby (sprzątanie pokoju)
  • Ignorowanie Law of Demeter (single dot)
  • Komentarze w kodzie (?)

JAK możemy sobie pomóc?

  • Truizmy?!
  • Opisowe i spójne nazewnictwo
  • Object Oriented Programming
  • Design Patterns
  • Znajomość podstawowych bibliotek (Array, Hash, String...)
  • Ekstrakcja nowych klas i metod (magiczny DRY)
  • Polimorfizm zamiast warunków w kodzie
  • Użycie strategi

JAK możemy sobie pomóc?

  • Użycie FormObjects (wiele modeli)
  • Użycie ServiceObjects
  • Użycie ValueObjects (Money, Temperature)
  • Użycie dekoratorów
  • Użycie fabryk obiektów (Factory)
  • Użycie prezenterów, adapterów (Api, widoki)
  • Zastąpienie callback'ów metodami

JAK możemy sobie pomóc?

  • SOLID
    • Single responsibility principle - Nigdy nie powinien istnieć więcej niż jeden powód do modyfikacji klasy
    • Open/closed principle - Przy zmianie wymagań nie powinien być zmieniany stary działający kod, ale dodawany nowy, który rozszerza zachowania.
    • Liskov substitution principle- Korzystanie z funkcji klasy bazowej musi być możliwe również w przypadku podstawienia instancji klas pochodnych.

JAK możemy sobie pomóc?

  • SOLID
    • Interface segregation principle - Klasy nie powinny zależeć od interfejsów, których nie używają.
    • Dependency inversion principle - Wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych - zależności między nimi powinny wynikać z abstrakcji / interfejsu.

wydajność

PROBLEMY

  • Legendarny brak wydajności ;)
  • Sam Ruby jest "wolny"
  • Duże zapotrzebowanie na RAM
  • Magia ActiveRecord sprzyja "dziwnym" rozwiązaniom
  • Nie wszystkie serwery webowe dla Rails są wydajne 

co możemy zrobić?

  • Zastosowanie jRuby, Rubinius zamiast MRI 
  • Caching, fragment caching
  • Pozbycie się wolnych zapytań do DB
  • Przesunięcie ciężaru w stronę bazy danych (views, materialized views)
  • Zastanowić się czy np. wyświetlanie 5000 rekordów na raz ma sens ;)
  • Ograniczenie użycia gemów
  • Użycie osobnego serwera do wyszukiwania pełnotekstowego (Solr, ElasticSearch, Algolia)

co możemy zrobić?

  • Użyć wydajniejszego serwera webowego: Puma, Passenger Enterprise (tuning)
  • Eksperymentować np. z Ruby GC
  • Skalować wertykalnie - większe serwery RoR + DB
  • Skalować horyzontalnie - np. poprzez mikroserwisy, sharding
  • Rozważenie które operacje mogą być wykonywane w tle (background processing) 
  • Zoptymalizować warstwę frontendową (np. CDN)

rynek i przyszłość

Rynek

  • Nadal wiele startupów używa RoR
  • 12.000.000 stron internetowych :)
  • Względnie szybkie wejście
  • Ruby to "przyjemny" język
  • Ogromna społeczność Open Source
  • Rails 5 - ciągły rozwój

przyszłość

  • "Moda" na języki funkcyjne
  • Erlang, Elixir, Phoenix
  • José Valim - kontrybutor Railsów
  • Wielu programistów RoR jest zainteresowanych :)

pytania?

dziękuję za uwagę! :)

Made with Slides.com