diff --git a/CHANGELOG.md b/CHANGELOG.md index 49016a68c3..ae615279d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ ### 🐛 Bug Fixes +- nil in OrderedCache ([#10647](https://github.com/blockscout/blockscout/pull/10647)) - Fix for metadata detection at ipfs protocol([#10646](https://github.com/blockscout/blockscout/pull/10646)) - Change default shrink internal_transactions table migration params ([#10644](https://github.com/blockscout/blockscout/pull/10644)) - Fix bug in update_replaced_transactions query ([#10634](https://github.com/blockscout/blockscout/issues/10634)) diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 473c2e0e76..c5f6d2d93e 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -1638,7 +1638,7 @@ defmodule Explorer.Chain do end defp block_from_cache(block_type, paging_options, necessity_by_association, options) do - case Blocks.take_enough(paging_options.page_size) do + case Blocks.atomic_take_enough(paging_options.page_size) do nil -> elements = fetch_blocks(block_type, paging_options, necessity_by_association, options) @@ -1652,7 +1652,7 @@ defmodule Explorer.Chain do end def uncles_from_cache(block_type, paging_options, necessity_by_association, options) do - case Uncles.take_enough(paging_options.page_size) do + case Uncles.atomic_take_enough(paging_options.page_size) do nil -> elements = fetch_blocks(block_type, paging_options, necessity_by_association, options) @@ -2620,7 +2620,7 @@ defmodule Explorer.Chain do if is_nil(paging_options.key) or paging_options.page_number == 1 do paging_options.page_size |> Kernel.+(1) - |> Transactions.take_enough() + |> Transactions.atomic_take_enough() |> case do nil -> transactions = fetch_recent_collated_transactions_for_rap(paging_options, necessity_by_association) diff --git a/apps/explorer/lib/explorer/chain/address.ex b/apps/explorer/lib/explorer/chain/address.ex index ad8f66980d..e931970698 100644 --- a/apps/explorer/lib/explorer/chain/address.ex +++ b/apps/explorer/lib/explorer/chain/address.ex @@ -328,7 +328,7 @@ defmodule Explorer.Chain.Address do if is_nil(paging_options.key) do paging_options.page_size - |> Accounts.take_enough() + |> Accounts.atomic_take_enough() |> case do nil -> get_addresses(options) diff --git a/apps/explorer/lib/explorer/chain/ordered_cache.ex b/apps/explorer/lib/explorer/chain/ordered_cache.ex index 9d2e797cdd..b27a79490b 100644 --- a/apps/explorer/lib/explorer/chain/ordered_cache.ex +++ b/apps/explorer/lib/explorer/chain/ordered_cache.ex @@ -112,6 +112,11 @@ defmodule Explorer.Chain.OrderedCache do """ @callback take_enough(integer()) :: [element] | nil + @doc """ + Behaves like `take_enough/1`, but addresses [#10445](https://github.com/blockscout/blockscout/issues/10445). + """ + @callback atomic_take_enough(integer()) :: [element] | nil + @doc """ Adds an element, or a list of elements, to the cache. When the cache is full, only the most prevailing elements will be stored, based @@ -204,6 +209,22 @@ defmodule Explorer.Chain.OrderedCache do end end + @impl OrderedCache + def atomic_take_enough(amount) do + items = + cache_name() + |> ConCache.ets() + |> :ets.tab2list() + + if amount <= Enum.count(items) - 1 do + items + |> Enum.reject(fn {key, _value} -> key == ids_list_key() end) + |> Enum.sort(&prevails?/2) + |> Enum.take(amount) + |> Enum.map(fn {_key, value} -> value end) + end + end + ### Updating function def remove_deleted_from_index({:delete, _cache_pid, id}) do