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

91eb330fb36d1e03c856574dfb77d2bc?s=128

Thibaut Barrère

July 12, 2016
Tweet

Transcript

  1. 1.

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

    d'application SaaS. Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  2. 3.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  3. 5.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  4. 6.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  5. 7.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  6. 9.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  7. 10.

    Importer la base Rails vers Ecto $ ecto.load --dump-path legacy-dumps/rails-db-seed.sql

    Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  8. 11.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  9. 12.

    Continuous integration ❤ (quelques heures pour la mise en place

    initiale sur CircleCI) Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  10. 13.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  11. 14.

    Zoomer sur un problème à la fois ExUnit.configure( exclude: :test,

    include: :focus, ... ) @tag :focus def test_this do # snip end Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  12. 15.

    Débugger une dépendance facilement $ atom deps/openmaize_jwt/lib config :mix_test_watch, [

    "deps.compile openmaize_jwt", "test" ] Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  13. 16.

    Adaptations Ecto <-> ActiveRecord schema "entries" do timestamps inserted_at: :created_at

    end Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  14. 17.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  15. 18.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  16. 19.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  17. 20.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  18. 21.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  19. 22.

    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("john@example.com") `` find_element(:id, "user_password") |> fill_field("testtest") Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  20. 23.

    Tests d'acceptance (hound + phantomjs ❤) find_element(:tag, "form") |> submit_element

    assert visible_page_text =~ ~r/Logged as john@example.com/i find_element(:link_text, "Logout") |> click assert visible_page_text =~ ~r/You have been logged out/i Thibaut Barrère (thibaut.barrere@gmail.com) - juillet 2016
  21. 24.

    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 (thibaut.barrere@gmail.com) - juillet 2016
  22. 25.

    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 (thibaut.barrere@gmail.com) - juillet 2016