fetch address counters async

In this PR (https://github.com/poanetwork/blockscout/pull/2636)
we started fetching transactions and rewards in parallel using
elixir tasks.

This PR uses similar approach to fetch validation and transaction
counters on address page.
pull/2663/head
Ayrat Badykov 5 years ago
parent cf6592d168
commit 87ab56b33d
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 8
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex
  2. 28
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  3. 8
      apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex
  4. 8
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.AddressContractController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1]
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token
@ -20,14 +20,16 @@ defmodule BlockScoutWeb.AddressContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count(address_hash),
validation_count: validation_count(address_hash)
transaction_count: transaction_count,
validation_count: validation_count
)
else
:error ->

@ -69,6 +69,34 @@ defmodule BlockScoutWeb.AddressController do
redirect(conn, to: address_transaction_path(conn, :index, id))
end
def transaction_and_validation_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
transaction_count_task =
Task.async(fn ->
transaction_count(address_hash)
end)
validation_count_task =
Task.async(fn ->
validation_count(address_hash)
end)
[transaction_count_task, validation_count_task]
|> Task.yield_many(:timer.seconds(30))
|> Enum.map(fn {_task, res} ->
case res do
{:ok, result} ->
result
{:exit, reason} ->
raise "Query fetching address counters terminated: #{inspect(reason)}"
nil ->
raise "Query fetching address counters timed out."
end
end)
|> List.to_tuple()
end
def transaction_count(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
Chain.total_transactions_sent_by_address(address_hash)
end

@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressReadContractController do
alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand
import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1]
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
def index(conn, %{"address_id" => address_hash_string}) do
address_options = [
@ -27,14 +27,16 @@ defmodule BlockScoutWeb.AddressReadContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
transaction_count: transaction_count(address_hash),
validation_count: validation_count(address_hash)
transaction_count: transaction_count,
validation_count: validation_count
)
else
:error ->

@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1]
import BlockScoutWeb.AddressController, only: [transaction_and_validation_count: 1]
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.TransactionView
@ -96,6 +96,8 @@ defmodule BlockScoutWeb.AddressTransactionController do
def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, validation_count} = transaction_and_validation_count(address_hash)
render(
conn,
"index.html",
@ -103,8 +105,8 @@ defmodule BlockScoutWeb.AddressTransactionController do
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"],
transaction_count: transaction_count(address_hash),
validation_count: validation_count(address_hash),
transaction_count: transaction_count,
validation_count: validation_count,
current_path: current_path(conn)
)
else

Loading…
Cancel
Save