Open o-jill opened 7 years ago
db = DB.new
db.change_something
class DB
def change_something
File.open(path, "r+") do |file|
file.flock(File::LOCK_EX)
data = file.read
edit_something(data)
file.write(data)
end
end
now, data shown below should be considered.
adding a user become thread-safer. c91c5c6fa. adding a game become thread-safer. c3b4eb43.
situations:
begin
db = DB.new
db.lock
db.read
db.change_something
db.write
rescure StandardError => e
puts "error:#{e}"
ensure
db.unlock
end
def lock
if !Dir.mkdir('lock.dir', 0o755)
// locked
else
// lock failed or some already locked.
end
end
def unlock
Dir.rmdir('lock.dir')
end
require 'timeout'
class AccessDenied < StandardError; end
def lock(&block)
# 10秒以内に終わらない場合はAccessDenied例外が発生
Timeout::timeout(10) do
open(File.join(Dir.tmpdir, 'my-application.lock'), 'w') do |f|
begin
f.flock(File::LOCK_EX)
block.call
ensure
f.flock(File::LOCK_UN)
end
end
end
rescue Exception => ex
raise AccessDenied.new('timeout')
end
lock do
# 排他処理
end
locking was implemented for UserInfoFile class in 25ff05cb51.
locking for Taikyoku/Taikyokuchu class was implemented but still only for append().
lock for Taikyoku/Taikyokuchu class was fully imlemented in 4afd8f8.
you have to use DB Server to avoid this issue!
now, data shown below should be considered.
match info file and jkf file are moved to mandatory because players and byouyomichan will update them asynchronously.
you may have to lock DB when you want to update it like
now locking files are used but it's not enough.