Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Alexander Khokhlov
@nots_ioNots.io
— Knock, knock
— An async template
— Who’s there?
Co-Founder
Nots.io
01
README.md
Code Comments
JavaDoc
GDocs
Confluence / DokuWiki / Wiki
Nots.io
Add docs for block of code,
function, module, file,
commit or branch
01
Notes, Tied
to Code
Easy to Discover
Easy to Explore
Easy to Get Scope
Easy to Ask and Discuss
01 • Nots.io
We Track
Relevance
You always know what’s fresh
and what’s not.
Promotes keeping docs
up-to-date.
Rewarding when everythin...
Discuss with
your Team
You won’t loose a dispute
that is written down.
It’s tied and has context
01 • Nots.io
And many more
awesome things
🔥
01 • Nots.io
Nots.io case
02
🏗
Choose File
page
02 • Nots.io case
02 • Nots.io case
In the
template
02 • Nots.io case
.branch-selector
= Notsapp.Renderer.simple_component({:"dropdown/dropdown", …})
%h2 File...
Microservices
YAY!
02 • Nots.io case
⛔
⛔
Blocking
04
.branch-selector
= Notsapp.Renderer.simple_component({:"dropdown/dropdown", …})
%h2 Files
.tree
= Notsapp....
But we want non-blocking
02
🚀
Good news: It’s doable!
02
But first
03
03
Phoenix
templates
But first
iolist() | iodata()
03 • Phoenix templates
IO.puts(["Hello, ", "Elixir"])
IO.puts ["Hello, ", 69, 108, 105, 120,...
But first
iolist() | iodata()
Does not allocate new strings: Repeated
chunks are created only once
Does not concatenate st...
Use iolist for I/O
iolist() | iodata()
With iolist & iodata work:
Console I/O functions
File I/O function
:gen_tcp.send()
...
What about Elixir
& Phoenix?
03 • Phoenix templates
At compile time Phoenix runs through the templates folder
Uses EEx to convert each template into a
function
phoenix/lib/ph...
At compile time
https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/
03 • Phoenix templates
At compile time
03 • Phoenix templates
At compile time
https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/
03 • Phoenix templates
At compile time
https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/
03 • Phoenix templates
d...
Gosh!
03 • Phoenix templates
At the end
of the day {:safe, [[["" | "<h1>Listing Users</h1>nn<ul>n "],
[[[[["" | "n <li>"] | "Jane"] | " ("] | "1"] | ")...
Rewind ⏪
04
.branch-selector
= Notsapp.Renderer.simple_component({:"dropdown/dropdown", …})
%h2 Files
.tree
= Notsapp.Rend...
What if we
return Task 🤔
Instead of HTML
04 • The solution
task = Task.async(fn -> do_heavy_work() end)
IO.puts "Do some m...
What if we
return Task 🤔
in pseudocode
04 • The solution
{:safe, [["" | "<div class="branch-selector"""> "],
["" | Task.as...
And when
everything is
ready — convert
04 • The solution
defmodule Notsapp.TemplateRenderer do
def process_rendered_templa...
Apply to
every view
04 • The solution
def view do
quote do
use Phoenix.View
use Notsapp.TemplateRenderer # <--
use Phoenix...
In parallel
Thank you
🤘
Alexander Khokhlov
point@nots.io
Nots.io
nots.io
blog.nots.io
@nots_io
facebook.com/nots.io
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  Elixir Club 13
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  Elixir Club 13
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  Elixir Club 13
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  Elixir Club 13
Prochain SlideShare
Chargement dans…5
×

— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | Elixir Club 13

32 vues

Publié le

Доповідь Олександра Хохлова, Founder Nots.io, на Elixir Club 13, Dnipro, 13.04.2019
Наступна конференція - http://www.elixirkyiv.club/



Elixir and Erlang platform are all about asynchronous communications. Why don’t we use this feature while rendering templates? In this talk, Alexander unveils how we in Nots.io split HTML documents into smaller pieces and render them in parallel.


Cлідкуйте за нами у соцмережах @ElixirClubUA та #ElixirClubUA
Анонси та матеріали конференцій - https://www.fb.me/ElixirClubUA
Новини - https://twitter.com/ElixirClubUA
Фото та невимушена атмосфера - https://www.instagram.com/ElixirClubUA
*Канал організаторів мітапа - https://t.me/incredevly

Publié dans : Technologie
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | Elixir Club 13

  1. 1. Alexander Khokhlov @nots_ioNots.io — Knock, knock — An async template — Who’s there?
  2. 2. Co-Founder Nots.io 01
  3. 3. README.md Code Comments JavaDoc GDocs Confluence / DokuWiki / Wiki
  4. 4. Nots.io Add docs for block of code, function, module, file, commit or branch 01
  5. 5. Notes, Tied to Code Easy to Discover Easy to Explore Easy to Get Scope Easy to Ask and Discuss 01 • Nots.io
  6. 6. We Track Relevance You always know what’s fresh and what’s not. Promotes keeping docs up-to-date. Rewarding when everything is ✅ 01 • Nots.io
  7. 7. Discuss with your Team You won’t loose a dispute that is written down. It’s tied and has context 01 • Nots.io
  8. 8. And many more awesome things 🔥 01 • Nots.io
  9. 9. Nots.io case 02 🏗
  10. 10. Choose File page 02 • Nots.io case
  11. 11. 02 • Nots.io case
  12. 12. In the template 02 • Nots.io case .branch-selector = Notsapp.Renderer.simple_component({:"dropdown/dropdown", …}) %h2 Files .tree = Notsapp.Renderer.simple_component({:"code-tree/tree", …})
  13. 13. Microservices YAY! 02 • Nots.io case
  14. 14. ⛔ ⛔ Blocking 04 .branch-selector = Notsapp.Renderer.simple_component({:"dropdown/dropdown", …}) %h2 Files .tree = Notsapp.Renderer.simple_component({:"code-tree/tree", …})
  15. 15. But we want non-blocking 02 🚀
  16. 16. Good news: It’s doable! 02
  17. 17. But first 03
  18. 18. 03 Phoenix templates
  19. 19. But first iolist() | iodata() 03 • Phoenix templates IO.puts(["Hello, ", "Elixir"]) IO.puts ["Hello, ", 69, 108, 105, 120, 105, 114] IO.puts ["Hello, ", [69, [108, [105, [120, [105, [114, ]]]]]]]
  20. 20. But first iolist() | iodata() Does not allocate new strings: Repeated chunks are created only once Does not concatenate strings/chars: Append to the list is O(1) and doesn’t require copying anything. 03 • Phoenix templates
  21. 21. Use iolist for I/O iolist() | iodata() With iolist & iodata work: Console I/O functions File I/O function :gen_tcp.send() :gen_udp.send() 03 • Phoenix templates
  22. 22. What about Elixir & Phoenix? 03 • Phoenix templates
  23. 23. At compile time Phoenix runs through the templates folder Uses EEx to convert each template into a function phoenix/lib/phoenix/template.ex 03 • Phoenix templates
  24. 24. At compile time https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/ 03 • Phoenix templates
  25. 25. At compile time 03 • Phoenix templates
  26. 26. At compile time https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/ 03 • Phoenix templates
  27. 27. At compile time https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/ 03 • Phoenix templates defmodule MyApp.SomeView do defp(index.html(var!(assigns))) do _ = var!(assigns) {:safe, [( tmp1 = ["" | "<h1>Listing Users</h1>nn<ul>n "] [tmp1 | case(for(user <- Phoenix.HTML.Engine.fetch_assign(var!(assigns), :users)) do {:safe, [( tmp1 = [( tmp1 = ["" | "n <li> “] [tmp1 | case(user.first_name()) do {:safe, data} -> data bin when is_binary(bin) -> Plug.HTML.html_escape(bin) other -> Phoenix.HTML.Safe.to_iodata(other) end] ) | " (“] … | "n</ul>nnThat's all!n"]}
  28. 28. Gosh! 03 • Phoenix templates
  29. 29. At the end of the day {:safe, [[["" | "<h1>Listing Users</h1>nn<ul>n "], [[[[["" | "n <li>"] | "Jane"] | " ("] | "1"] | ")</li>n "], [[[[["" | "n <li>"] | "Joe"] | " ("] | "2"] | ")</li>n "]] | "n</ul>nnThat's all!n"]} iolist In runtime 03 • Phoenix templates
  30. 30. Rewind ⏪ 04 .branch-selector = Notsapp.Renderer.simple_component({:"dropdown/dropdown", …}) %h2 Files .tree = Notsapp.Renderer.simple_component({:"code-tree/tree", …})
  31. 31. What if we return Task 🤔 Instead of HTML 04 • The solution task = Task.async(fn -> do_heavy_work() end) IO.puts "Do some more work" result = Task.await(task)
  32. 32. What if we return Task 🤔 in pseudocode 04 • The solution {:safe, [["" | "<div class="branch-selector"""> "], ["" | Task.async(fn -> render_dropdown() end)] , ["" | "n</div>nn"]]}
  33. 33. And when everything is ready — convert 04 • The solution defmodule Notsapp.TemplateRenderer do def process_rendered_template([h|t]) do [process_rendered_template(h) | process_rendered_template(t)] end def process_rendered_template(%Notsapp.CljTask{task: task}) do Task.await(task) end def process_rendered_template(e) do e end defmacro __using__(_opts) do quote do def render(template, assigns) do {:safe, io_list} = render_template(template, assigns) {:safe, process_rendered_template(io_list)} end end end end
  34. 34. Apply to every view 04 • The solution def view do quote do use Phoenix.View use Notsapp.TemplateRenderer # <-- use Phoenix.HTML
  35. 35. In parallel
  36. 36. Thank you 🤘
  37. 37. Alexander Khokhlov point@nots.io Nots.io nots.io blog.nots.io @nots_io facebook.com/nots.io

×