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
block_type = Keyword.get(options, :block_type, "Block")
if block_type == "Block" && !paging_options.key && BlocksCache.enough_elements?(paging_options.page_size) do
cached_blocks = BlocksCache.blocks()
if block_type == "Block" && !paging_options.key do
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
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()
fetch_blocks(block_type, paging_options, necessity_by_association)
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 """
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
"""
alias Explorer.Repo
@block_numbers_key "block_numbers"
@cache_name :blocks
@number_of_elements 60
@ -22,6 +24,24 @@ defmodule Explorer.Chain.BlocksCache do
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
ConCache.size(@cache_name) > number + 1
end
@ -54,7 +74,8 @@ defmodule Explorer.Chain.BlocksCache do
end
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])
end
end

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

Loading…
Cancel
Save