Problem: a lot of problems are created by tracking the importing progress on multiple tables. Querying and updating involves as such heavy operations and this is also the cause for inconsistencies. Solution: use a new table to track the progress of block's data indexing. By using a specific table, whose rows are deleted when there are no more pending operations on the relative block, we make joins quick and keep them to a minimum. This is also meant to simplify all inserts and updates and only perform deletes when strictly necessary.pull/2888/head
parent
25ceebf080
commit
7d346d9975
@ -0,0 +1,46 @@ |
||||
defmodule Explorer.Chain.PendingBlockOperation do |
||||
@moduledoc """ |
||||
Tracks a block that has pending operations. |
||||
""" |
||||
|
||||
use Explorer.Schema |
||||
|
||||
alias Explorer.Chain.{Block, Hash} |
||||
|
||||
@required_attrs ~w(block_hash)a |
||||
|
||||
@typedoc """ |
||||
* `block_hash` - the hash of the block that has pending operations. |
||||
""" |
||||
@type t :: %__MODULE__{ |
||||
block_hash: Hash.Full.t() |
||||
} |
||||
|
||||
@primary_key false |
||||
schema "pending_block_operations" do |
||||
timestamps() |
||||
|
||||
belongs_to(:block, Block, foreign_key: :block_hash, primary_key: true, references: :hash, type: Hash.Full) |
||||
end |
||||
|
||||
def changeset(%__MODULE__{} = pending_ops, attrs) do |
||||
pending_ops |
||||
|> cast(attrs, @required_attrs) |
||||
|> validate_required(@required_attrs) |
||||
|> foreign_key_constraint(:block_hash) |
||||
|> unique_constraint(:block_hash, name: :pending_block_operations_pkey) |
||||
end |
||||
|
||||
@doc """ |
||||
Returns all pending block operations with the `block_hash` in the given list, |
||||
using "FOR UPDATE" to grab ShareLocks in order (see docs: sharelocks.md) |
||||
""" |
||||
def fetch_and_lock_by_hashes(hashes) when is_list(hashes) do |
||||
from( |
||||
pending_ops in __MODULE__, |
||||
where: pending_ops.block_hash in ^hashes, |
||||
order_by: [asc: pending_ops.block_hash], |
||||
lock: "FOR UPDATE" |
||||
) |
||||
end |
||||
end |
@ -0,0 +1,14 @@ |
||||
defmodule Explorer.Repo.Migrations.CreatePendingBlockOperations do |
||||
use Ecto.Migration |
||||
|
||||
def change do |
||||
create table(:pending_block_operations, primary_key: false) do |
||||
add(:block_hash, references(:blocks, column: :hash, type: :bytea, on_delete: :delete_all), |
||||
null: false, |
||||
primary_key: true |
||||
) |
||||
|
||||
timestamps(null: false, type: :utc_datetime_usec) |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue