Class: Kitsune::Kit::StateStore
- Inherits:
-
Kitsune::Kit::StateStores::Store
- Object
- Kitsune::Kit::StateStores::Store
- Kitsune::Kit::StateStore
- Defined in:
- lib/kitsune/kit/state_store.rb
Constant Summary collapse
- SCHEMA_VERSION =
1
Instance Method Summary collapse
- #delete(environment) ⇒ Object
-
#initialize(root: Dir.pwd) ⇒ StateStore
constructor
A new instance of StateStore.
- #read(environment) ⇒ Object
- #update(environment) ⇒ Object
- #with_execution_lock(environment) ⇒ Object
- #write(environment, state) ⇒ Object
Constructor Details
#initialize(root: Dir.pwd) ⇒ StateStore
Returns a new instance of StateStore.
16 17 18 19 |
# File 'lib/kitsune/kit/state_store.rb', line 16 def initialize(root: Dir.pwd) super() @directory = Pathname(root)..join(".kitsune/state") end |
Instance Method Details
#delete(environment) ⇒ Object
53 54 55 56 57 58 59 60 |
# File 'lib/kitsune/kit/state_store.rb', line 53 def delete(environment) with_lock(environment) do next unless state_path(environment).file? state_path(environment).delete true end end |
#read(environment) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/kitsune/kit/state_store.rb', line 21 def read(environment) path = state_path(environment) return empty_state(environment) unless path.file? with_lock(environment, shared: true) do parsed = JSON.parse(path.read) validate!(parsed, environment) parsed end rescue JSON::ParserError => e raise Errors::ConfigurationError.new( "state file is invalid JSON: #{path}", hint: "Restore the state backup or import the environment again.", context: { cause: e. } ) end |
#update(environment) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/kitsune/kit/state_store.rb', line 38 def update(environment) with_lock(environment) do current = read_without_lock(environment) updated = yield(deep_copy(current)) updated["updated_at"] = Time.now.utc.iso8601(6) validate!(updated, environment) write_atomically(state_path(environment), JSON.pretty_generate(updated) << "\n") deep_copy(updated) end end |
#with_execution_lock(environment) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/kitsune/kit/state_store.rb', line 62 def with_execution_lock(environment) FileUtils.mkdir_p(@directory, mode: 0o700) path = @directory.join("#{safe_environment(environment)}.operation.lock") File.open(path, File::RDWR | File::CREAT, 0o600) do |file| locked = file.flock(File::LOCK_EX | File::LOCK_NB) unless locked raise Errors::UnsafeOperationError.new( "another mutating operation is active for #{environment}", hint: "Wait for it to finish or stop it safely before retrying." ) end yield ensure file.flock(File::LOCK_UN) if locked end end |
#write(environment, state) ⇒ Object
49 50 51 |
# File 'lib/kitsune/kit/state_store.rb', line 49 def write(environment, state) update(environment) { state } end |