preload associations

pull/2075/head
Ayrat Badykov 6 years ago
parent b3892ba5b6
commit 6a970468c1
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 32
      apps/explorer/lib/explorer/chain.ex
  2. 23
      apps/explorer/lib/explorer/chain/blocks_cache.ex
  3. 20
      apps/explorer/test/explorer/chain/blocks_cache_test.exs

@ -1152,21 +1152,33 @@ defmodule Explorer.Chain do
paging_options = Keyword.get(options, :paging_options) || @default_paging_options paging_options = Keyword.get(options, :paging_options) || @default_paging_options
block_type = Keyword.get(options, :block_type, "Block") block_type = Keyword.get(options, :block_type, "Block")
if block_type == "Block" && !paging_options.key && BlocksCache.enough_elements?(paging_options.page_size) do if block_type == "Block" && !paging_options.key do
cached_blocks = BlocksCache.blocks() if BlocksCache.enough_elements?(paging_options.page_size) do
cached_blocks = BlocksCache.blocks()
Enum.slice(cached_blocks, 0, paging_options.page_size) Enum.slice(cached_blocks, 0, paging_options.page_size)
else
elements = fetch_blocks(block_type, paging_options, necessity_by_association)
BlocksCache.rewrite_cache(elements)
elements
end
else else
Block fetch_blocks(block_type, paging_options, necessity_by_association)
|> Block.block_type_filter(block_type)
|> page_blocks(paging_options)
|> limit(^paging_options.page_size)
|> order_by(desc: :number)
|> join_associations(necessity_by_association)
|> Repo.all()
end end
end end
defp fetch_blocks(block_type, paging_options, necessity_by_association) do
Block
|> Block.block_type_filter(block_type)
|> page_blocks(paging_options)
|> limit(^paging_options.page_size)
|> order_by(desc: :number)
|> join_associations(necessity_by_association)
|> Repo.all()
end
@doc """ @doc """
Map `block_number`s to their `t:Explorer.Chain.Block.t/0` `hash` `t:Explorer.Chain.Hash.Full.t/0`. Map `block_number`s to their `t:Explorer.Chain.Block.t/0` `hash` `t:Explorer.Chain.Hash.Full.t/0`.

@ -3,6 +3,8 @@ defmodule Explorer.Chain.BlocksCache do
Caches the last imported blocks Caches the last imported blocks
""" """
alias Explorer.Repo
@block_numbers_key "block_numbers" @block_numbers_key "block_numbers"
@cache_name :blocks @cache_name :blocks
@number_of_elements 60 @number_of_elements 60
@ -22,6 +24,24 @@ defmodule Explorer.Chain.BlocksCache do
end end
end end
def rewrite_cache(elements) do
numbers = block_numbers()
ConCache.delete(@cache_name, @block_numbers_key)
numbers
|> Enum.each(fn number ->
ConCache.delete(@cache_name, number)
end)
elements
|> Enum.reduce([], fn element, acc ->
put_block(element, acc)
[element.number | acc]
end)
end
def enough_elements?(number) do def enough_elements?(number) do
ConCache.size(@cache_name) > number + 1 ConCache.size(@cache_name) > number + 1
end end
@ -54,7 +74,8 @@ defmodule Explorer.Chain.BlocksCache do
end end
defp put_block(block, numbers) do defp put_block(block, numbers) do
ConCache.put(@cache_name, block.number, block) block_with_preloads = Repo.preload(block, [:transactions, [miner: :names], :rewards])
ConCache.put(@cache_name, block.number, block_with_preloads)
ConCache.put(@cache_name, @block_numbers_key, [block.number | numbers]) ConCache.put(@cache_name, @block_numbers_key, [block.number | numbers])
end end
end end

@ -2,6 +2,7 @@ defmodule Explorer.Chain.BlocksCacheTest do
use Explorer.DataCase use Explorer.DataCase
alias Explorer.Chain.BlocksCache alias Explorer.Chain.BlocksCache
alias Explorer.Repo
setup do setup do
Supervisor.terminate_child(Explorer.Supervisor, ConCache) Supervisor.terminate_child(Explorer.Supervisor, ConCache)
@ -11,7 +12,7 @@ defmodule Explorer.Chain.BlocksCacheTest do
describe "update/1" do describe "update/1" do
test "adds a new value to cache" do test "adds a new value to cache" do
block = insert(:block) block = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards])
BlocksCache.update(block) BlocksCache.update(block)
@ -37,4 +38,21 @@ defmodule Explorer.Chain.BlocksCacheTest do
assert Enum.map(BlocksCache.blocks(), & &1.number) == new_blocks assert Enum.map(BlocksCache.blocks(), & &1.number) == new_blocks
end end
end end
describe "rewrite_cache/1" do
test "updates cache" do
block = insert(:block)
BlocksCache.update(block)
block1 = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards])
block2 = insert(:block) |> Repo.preload([:transactions, [miner: :names], :rewards])
new_blocks = [block1, block2]
BlocksCache.rewrite_cache(new_blocks)
assert BlocksCache.blocks() == [block1, block2]
end
end
end end

Loading…
Cancel
Save