Fixes issues related to parallel updates.
parent
2dd42f3a30
commit
48cf3c23be
25
spec/test.cr
25
spec/test.cr
|
@ -545,6 +545,31 @@ describe "DODB::DataBase" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "does parallel-safe updates" do
|
||||
db = DODB::SpecDataBase.new
|
||||
db_entries_by_name = db.new_index "name", &.name
|
||||
|
||||
# We’ll be storing an integer in the "klass" field, and incrementing
|
||||
# it in forks in a second time.
|
||||
db << Ship.new("test", "0")
|
||||
|
||||
processes = [] of Process
|
||||
fork_count.times do |fork_id|
|
||||
processes << Process.fork do
|
||||
entries_per_fork.times do |entry_id|
|
||||
db_entries_by_name.safe_get "test" do |entry|
|
||||
entry.klass = (entry.klass.to_i + 1).to_s
|
||||
|
||||
db_entries_by_name.update "test", entry
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
processes.each &.wait
|
||||
|
||||
db_entries_by_name.get("test").klass.should eq((fork_count * entries_per_fork).to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -72,13 +72,16 @@ class DODB::Index(V) < DODB::Indexer(V)
|
|||
nil
|
||||
end
|
||||
|
||||
# FIXME: Unlock on exception.
|
||||
def safe_get(index : String) : Nil
|
||||
@storage.request_lock @name, index
|
||||
internal_key = get_key(index).to_s
|
||||
@storage.request_lock internal_key
|
||||
|
||||
yield get index
|
||||
|
||||
@storage.release_lock internal_key
|
||||
@storage.release_lock @name, index
|
||||
end
|
||||
|
||||
def safe_get?(index : String, &block : Proc(V | Nil, Nil)) : Nil
|
||||
|
|
Loading…
Reference in New Issue