Module: Vivlio::Starter::CLI::BuildCommands::BuildLock
- Defined in:
- lib/vivlio/starter/cli/build/build_lock.rb
Overview
同一プロジェクトでの vs build 多重実行を防ぐ排他ロック機構。.cache/vs/.build.lock に対し File::LOCK_EX | File::LOCK_NB でフロックを取得し、競合時は AlreadyLockedError を送出する。
Defined Under Namespace
Classes: AlreadyLockedError
Constant Summary collapse
- LOCK_FILENAME =
'.build.lock'
Class Method Summary collapse
- .build_conflict_message(lock_path, existing) ⇒ Object
- .read_lock_info(file) ⇒ Object
-
.with_lock { ... } ⇒ Object
ロックを取得してブロックを実行する。終了時に自動で解放する。.
- .write_lock_info(file) ⇒ Object
Class Method Details
.build_conflict_message(lock_path, existing) ⇒ Object
80 81 82 83 84 85 86 87 88 |
# File 'lib/vivlio/starter/cli/build/build_lock.rb', line 80 def (lock_path, existing) hint = existing.to_s.strip hint_section = hint.empty? ? '' : "\n 既存ロック情報:\n#{hint.lines.map { " #{it}" }.join}" <<~MSG.strip 別の vs build プロセスがこのプロジェクトで実行中です。 ロックファイル: #{lock_path}#{hint_section} 完了を待ってから再実行するか、該当プロセスを終了してください。 MSG end |
.read_lock_info(file) ⇒ Object
66 67 68 69 70 71 |
# File 'lib/vivlio/starter/cli/build/build_lock.rb', line 66 def read_lock_info(file) file.rewind file.read rescue StandardError '' end |
.with_lock { ... } ⇒ Object
ロックを取得してブロックを実行する。終了時に自動で解放する。
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/vivlio/starter/cli/build/build_lock.rb', line 44 def with_lock lock_path = File.join(Vivlio::Starter::CLI::Common.ensure_cache_dir!, LOCK_FILENAME) # ブロック形式は flock を yield 越しに保持できないため使用しない file = File.open(lock_path, File::RDWR | File::CREAT, 0o644) # rubocop:disable Style/FileOpen unless file.flock(File::LOCK_EX | File::LOCK_NB) existing = read_lock_info(file) file.close raise AlreadyLockedError, (lock_path, existing) end write_lock_info(file) begin yield ensure file.flock(File::LOCK_UN) file.close FileUtils.rm_f(lock_path) end end |
.write_lock_info(file) ⇒ Object
73 74 75 76 77 78 |
# File 'lib/vivlio/starter/cli/build/build_lock.rb', line 73 def write_lock_info(file) file.truncate(0) file.rewind file.write("pid=#{Process.pid}\nstarted=#{Time.now.iso8601}\n") file.flush end |