phronomy 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phronomy
4
- module StateStore
5
- # Abstract base class for workflow state persistence backends.
6
- #
7
- # Subclasses must implement {#load}, {#save}, and {#delete}.
8
- # A snapshot is a plain +Hash+ with two keys:
9
- # +:fields+ — output of +context.to_h+
10
- # +:phase+ — +context.phase.to_s+
11
- #
12
- # @example Implementing a custom backend
13
- # class MyStore < Phronomy::StateStore::Base
14
- # def load(thread_id) = MyRecord.find_by(thread_id:)&.to_h
15
- # def save(thread_id, snapshot) = MyRecord.upsert(thread_id:, data: snapshot)
16
- # def delete(thread_id) = MyRecord.where(thread_id:).delete_all
17
- # end
18
- class Base
19
- # Load the stored snapshot for +thread_id+.
20
- #
21
- # @param thread_id [String]
22
- # @return [Hash, nil] stored snapshot hash, or +nil+ if absent
23
- # @api public
24
- def load(thread_id)
25
- raise NotImplementedError, "#{self.class}#load is not implemented"
26
- end
27
-
28
- # Persist +snapshot+ for +thread_id+. Overwrites any existing snapshot.
29
- #
30
- # @param thread_id [String]
31
- # @param snapshot [Hash] serialisable hash of workflow state
32
- # @return [void]
33
- # @api public
34
- def save(thread_id, snapshot)
35
- raise NotImplementedError, "#{self.class}#save is not implemented"
36
- end
37
-
38
- # Delete the stored snapshot for +thread_id+. No-op if absent.
39
- #
40
- # @param thread_id [String]
41
- # @return [void]
42
- # @api public
43
- def delete(thread_id)
44
- raise NotImplementedError, "#{self.class}#delete is not implemented"
45
- end
46
- end
47
- end
48
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phronomy
4
- module StateStore
5
- # Thread-safe in-process state store backed by a plain Ruby Hash.
6
- #
7
- # Used as the recommended default for single-process applications and tests.
8
- # State does not survive process restart.
9
- #
10
- # @example
11
- # store = Phronomy::StateStore::InMemory.new
12
- # store.save("t1", { fields: { count: 1 }, phase: "__end__" })
13
- # store.load("t1") # => { fields: { count: 1 }, phase: "__end__" }
14
- # store.delete("t1")
15
- # store.load("t1") # => nil
16
- class InMemory < Base
17
- def initialize
18
- @data = {}
19
- @mutex = Mutex.new
20
- end
21
-
22
- # @param thread_id [String]
23
- # @return [Hash, nil]
24
- # @api public
25
- def load(thread_id)
26
- @mutex.synchronize do
27
- snap = @data[thread_id]
28
- snap ? deep_dup(snap) : nil
29
- end
30
- end
31
-
32
- # @param thread_id [String]
33
- # @param snapshot [Hash]
34
- # @return [void]
35
- # @api public
36
- def save(thread_id, snapshot)
37
- @mutex.synchronize { @data[thread_id] = deep_dup(snapshot) }
38
- nil
39
- end
40
-
41
- # @param thread_id [String]
42
- # @return [void]
43
- # @api public
44
- def delete(thread_id)
45
- @mutex.synchronize { @data.delete(thread_id) }
46
- nil
47
- end
48
-
49
- private
50
-
51
- # Recursively deep-duplicates a plain-data value (Hash, Array, or scalar).
52
- # Sufficient for snapshot data which consists of JSON-compatible types.
53
- def deep_dup(val)
54
- case val
55
- when Hash then val.each_with_object({}) { |(k, v), h| h[k] = deep_dup(v) }
56
- when Array then val.map { |v| deep_dup(v) }
57
- else val.frozen? ? val : (val.dup rescue val) # rubocop:disable Style/RescueModifier
58
- end
59
- end
60
- end
61
- end
62
- end