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

Keep Phoenix App Productivity

kanmo
June 16, 2018

Keep Phoenix App Productivity

Erlang & Elixir Fest 2018 発表資料

kanmo

June 16, 2018
Tweet

More Decks by kanmo

Other Decks in Programming

Transcript

  1. Who am I • Akihide Kan(@kanmo_ak) • XFLAG(mixi, Inc.) •

    ໿൒೥લʹݱࡏͷϓϩδΣΫτʢElixirͷήʔϜαʔό ։ൃʣʹࢀՃ
  2. Running for 1 year $ grep ‘defmodule’ apps/**/*.ex{,s} | wc

    -l 4083 $ wc -l apps/**/*.ex{,s} | tail -n1 326131 total
  3. Distillery Release # rel/config.exs release :test_app_all do set version: “0.0.1"

    set applications: [:test_app_api, :test_app_socket, :test_app_cs, :test_app_cms, :test_app_to ols] … end # release separately release :test_app_api do set version: current_version(:test_app_api) set applications: [:test_app_api] … end
  4. Umbrella or Microservices Repository Interface Deploy Umbrella Single Via subapp

    Both(one app or separately) Microservices Separate Repositories Defined Interface Separately
  5. Elixir Compile • Elixir͸macroʹΑͬͯmeta programmingͷػೳΛ࣮ ݱ • macro͸ίϯύΠϧ࣌ʹͷΈධՁ • Compile

    time dependencies͕ੜ·ΕΔͱͦͷϞδϡʔ ϧʹؔ࿈ͨ͠Ϟδϡʔϧ΋ίϯύΠϧର৅ʹͳΔ
  6. Compile Time Dependencies defmodule MacroTest do require MacroA def test,

    do: MacroA.use_macro("hello") end defmodule MacroA do defmacro use_macro(x) do if ModuleA.func() do quote(do: unquote("#{x} macro")) else quote(do: unquote("#{x} dependency")) end end end
  7. Compile Time Dependencies defmodule MacroTest do require MacroA def test,

    do: MacroA.use_macro("hello") end defmodule MacroA do defmacro use_macro(x) do if ModuleA.func() do quote(do: unquote("#{x} macro")) else quote(do: unquote("#{x} dependency")) end end end
  8. Compile Time Dependencies defmodule StructTest do def test do %StructA{field:

    “hello”} end end defmodule StructA do defstruct [:field] end
  9. Compile Time Dependencies defmodule StructTest do def test do %StructA{field:

    “hello”} end end defmodule StructA do defstruct [:field] end
  10. Compile Time Dependencies defmodule Test do import ModuleA end defmodule

    BehaviourTest do @behaviour BehaviourA def test(x), do: x end
  11. Compile Time Dependencies defprotocol ProtocolA do def test(x) end #

    protocol_impl.ex defimpl ProtocolA, for: StructA do def test(_), do: “test” end # protocol_caller.ex defmodule ProtocolCaller do def use_protocol(x), do ProtocolA.test(x) end end
  12. Compile Time Dependencies defprotocol ProtocolA do def test(x) end #

    protocol_impl.ex defimpl ProtocolA, for: StructA do def test(_), do: “test” end # protocol_caller.ex defmodule ProtocolCaller do def use_protocol(x), do ProtocolA.test(x) end end
  13. Mix xref $ mix xref graph —format dot digraph "xref

    graph" { "lib/macro_a.ex" "lib/macro_a.ex" -> “lib/module_a.ex" "lib/macro_test.ex" "lib/macro_test.ex" -> "lib/macro_a.ex" [label="(compile)"] }
  14. Mix xref $ mix xref graph —format dot digraph "xref

    graph" { "lib/macro_a.ex" "lib/macro_a.ex" -> “lib/module_a.ex" "lib/macro_test.ex" "lib/macro_test.ex" -> "lib/macro_a.ex" [label="(compile)"] }
  15. Dirty Trick defmodule MacroTest do def test() do func_map =

    %{key1: Test.Module.Function1, key2: Test.Module.Function2} end end
  16. Dirty Trick defmodule MacroTest do def test() do func_map =

    %{key1: Module.concat([Test, Module, Function1], key2: Module.concat([Test, Module, Function2]} end end defmodule MacroTest do def test() do func_map = %{key1: Test.Module.Function1, key2: Test.Module.Function2} end end
  17. IEx Helper # .iex.exs defmodule IExHelper do def rerun_spec(file_name) do

    Mix.Task.reenable “espec” … Code.load_file(file_name) |> get_in([Access.at(0), Access.elem(0)]) |> ESpec.SuiteRunner.run(ESpec.Configuration.all) |> ESpec.Output.final_result() end end
  18. $=proc:<0.13622.1> State: Garbing Name: ‘Elixir.Timex_meck' Spawned as: proc_lib:init_p/5 Spawned by:

    <0.4265.0> Started: Wed May 17 05:15:18 2017 Message queue length: 4 Number of heap fragments: 0 Heap fragment data: 14666 Link list: [<0.4265.0>, {from,<0.16290.3>,#Ref<0.0.5505025.4620>}] Reductions: 79249321 Stack+heap: 164783480 … Remsh remshͰىಈதͷphoenixϓϩηεʹ઀ଓͯ͠ௐࠪͰ͖Δ
  19. $=proc:<0.13622.1> State: Garbing Name: ‘Elixir.Timex_meck' Spawned as: proc_lib:init_p/5 Spawned by:

    <0.4265.0> Started: Wed May 17 05:15:18 2017 Message queue length: 4 Number of heap fragments: 0 Heap fragment data: 14666 Link list: [<0.4265.0>, {from,<0.16290.3>,#Ref<0.0.5505025.4620>}] Reductions: 79249321 Stack+heap: 164783480 … $ iex —name “app_name” —cookie “mycookie” —remsh “app_name-11111@hostname iex()1> Process.whereis(Elixir.Timex_meck) #PID<0.19553.2> iex()2>:erlang.process_info(pid(“0.19553.2”), :total_heap_s ize) {:total_heap_size, 224366925} Remsh remshͰىಈதͷphoenixϓϩηεʹ઀ଓͯ͠ௐࠪͰ͖Δ
  20. ·ͱΊ • ΞϓϦέʔγϣϯ͕େ͖͘ͳΔʹͭΕͯੜ࢈ੑ͕Լ͕Δ໰୊͕ग़ͯ ͘Δʢcompile, test, deploy…ʣ • Umbrella͸ϓϩδΣΫτ෼ׂΛ؆୯ʹͰ͖ΔΑ͏ʹαϙʔτ͠ ͯ͘ΕΔ •

    Compileର৅͕ଟ͍৔߹͸ɺແବͳCompile Time DependenciesΛ࡟আ͢Δ • Ϣʔβʔͷ઀ଓ؅ཧͱϩδοΫΛॲཧ͢ΔαʔόΛ෼͚ͨ