Upgrade to Pro — share decks privately, control downloads, hide ads and more …

De Rails à Phoenix - retour d'expérience sur une réécriture d'application SaaS

De Rails à Phoenix - retour d'expérience sur une réécriture d'application SaaS

Thibaut Barrère

July 12, 2016
Tweet

More Decks by Thibaut Barrère

Other Decks in Programming

Transcript

  1. Rails -> Phoenix Retour d'expérience sur une rewrite (en cours)

    d'application SaaS. Thibaut Barrère ([email protected]) - juillet 2016
  2. Pourquoi une rewrite? 4 Elixir flaggé "stratégique" sur mon radar

    tech ! 4 Produits SaaS et applications internes (dev solo) 4 Consulting (scalabilité, ETL, ...) 4 Robotique, IoT, ETL, Streaming. 4 Rewrite = apprentissage & comparaison 4 Comparaison des écosystèmes Thibaut Barrère ([email protected]) - juillet 2016
  3. Comment débuter 4 "Programming Elixir" de A à Z 4

    Koans (http://github.com/thbar/elixir-playground) test "function declaration and invocation" do sum = fn (a, b) -> a + b end assert sum.(2, 10) == 12 tuple_sum = fn { a, b, c, d } -> a + b + c + d end assert tuple_sum.({ 10, 100, 1000, 10000 }) == 11110 end Thibaut Barrère ([email protected]) - juillet 2016
  4. Frictions 4 Vendor lock-in Ruby: 4 Productivité très forte. 4

    Ecosystème très mûr et large. 4 Zone de confort énorme. 4 Accepter d'être lent au début. Thibaut Barrère ([email protected]) - juillet 2016
  5. Motivations 4 Faire plus avec moins de personnes. 4 Scaler

    plus fort avec moins de machines. 4 Aller vers l'internet des choses, le streaming, le flux continu de données, le très scalable, le redondant. 4 Même "bon feeling" qu'avec Rails en 2005. Thibaut Barrère ([email protected]) - juillet 2016
  6. Exporter une base de dév depuis Rails $ rake db:seed

    $ pg_dump -O -x wisecash_dev -f legacy-dumps/rails-db-seed.sql Thibaut Barrère ([email protected]) - juillet 2016
  7. Importer la base Rails vers Ecto, automatiquement, avant les tests

    defp aliases do [ "test": [ "ecto.create --quiet", "ecto.load --dump-path legacy-dumps/rails-db-seed.sql", "test" ] ] end Thibaut Barrère ([email protected]) - juillet 2016
  8. Continuous integration ❤ (quelques heures pour la mise en place

    initiale sur CircleCI) Thibaut Barrère ([email protected]) - juillet 2016
  9. Se mettre à l'aise pour expérimenter 4 Feedback-loop rapide avec

    mix_test_watch 4 Tests "exploratoires" 4 Colorisation de l'output avec apex defp deps do [ {:mix_test_watch, "~> 0.2", only: :dev}, {:apex, "~> 0.4.0", only: [:dev, :test]} ] end Thibaut Barrère ([email protected]) - juillet 2016
  10. Zoomer sur un problème à la fois ExUnit.configure( exclude: :test,

    include: :focus, ... ) @tag :focus def test_this do # snip end Thibaut Barrère ([email protected]) - juillet 2016
  11. Débugger une dépendance facilement $ atom deps/openmaize_jwt/lib config :mix_test_watch, [

    "deps.compile openmaize_jwt", "test" ] Thibaut Barrère ([email protected]) - juillet 2016
  12. Evènements récurrents Plusieurs tentatives: 1. Postgres generate_series (ne colle pas

    au besoin) ! 2. Fonction PL/pgSQL (des contournements à faire) " 3. Fonction Elixir (terminée en quelques heures) # Merci Timex.shift Thibaut Barrère ([email protected]) - juillet 2016
  13. Queries SQL sur des fonctions (avec Ecto 2) Logger.configure(level: :debug)

    Ecto.Adapters.SQL.query!(WisecashEx.Repo, query, [from, to]) def postgres_setup!(repo) do source = File.read!(query_file("generate_recurring_events.sql")) Ecto.Adapters.SQL.query!(repo, source, []) end 4 Ecto = plus limité que Sequel en Ruby Thibaut Barrère ([email protected]) - juillet 2016
  14. Authentification Choix large (comme avec Rails en 2005): 4 Guardian

    (pas de gestion de BDD, JWT) 4 Openmaize (BDD, code généré, JWT) ! 4 Addict 4 ... Mais quelle solution sera réellement pérenne ??? Thibaut Barrère ([email protected]) - juillet 2016
  15. Adaptation du schéma de Rails & Devise vers Openmaize schema

    "users" do field :email, :string field :encrypted_password, :string field :password, :string, virtual: true field :role, :string, virtual: true, default: "user" timestamps inserted_at: :created_at end config :openmaize, hash_name: :encrypted_password Thibaut Barrère ([email protected]) - juillet 2016
  16. Openmaize dans le contrôleur plug Openmaize.Login, [ db_module: WisecashEx.OpenmaizeEcto, unique_id:

    :email ] when action in [:login_user] Reprise en main du code généré par Openmaize. Thibaut Barrère ([email protected]) - juillet 2016
  17. Tests d'acceptance (hound + phantomjs ❤) navigate_to("/") "/" = current_path

    find_element(:link_text, "Login") |> click "/login" = current_path find_element(:id, "user_email") |> fill_field("[email protected]") `` find_element(:id, "user_password") |> fill_field("testtest") Thibaut Barrère ([email protected]) - juillet 2016
  18. Tests d'acceptance (hound + phantomjs ❤) find_element(:tag, "form") |> submit_element

    assert visible_page_text =~ ~r/Logged as [email protected]/i find_element(:link_text, "Logout") |> click assert visible_page_text =~ ~r/You have been logged out/i Thibaut Barrère ([email protected]) - juillet 2016
  19. Déploiement 4 Heroku: build-pack fonctionnel rapidement 4 EngineYard: custom cookbooks,

    pas horrible 4 Pas de hot-reloading pour le moment Thibaut Barrère ([email protected]) - juillet 2016
  20. Mes conclusions pour le moment 4 Données immutables = fondation

    solide 4 Effets de 2nd ordre (levier, composabilité) 4 TDD = aide beaucoup pour prendre en main 4 Librairies jeunes (perte de temps - maintenance) 4 Confort très similaire à Ruby en régime de croisière 4 Moins de "compromis duct-tape" qu'avec Ruby Thibaut Barrère ([email protected]) - juillet 2016