ask-graph 0.2.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 965f606d4e8a059634acd10ed0e2fbf96c159ba487d30f5f2edcec9bb1b75b89
4
- data.tar.gz: b419551a611da8cd81eb7ab0d31bdf0c8213d8ed829e6a30981fe0d561938e84
3
+ metadata.gz: c3062914e848e9fea15dd9b02bd001946b7a3fd0ab015a1805b4e21a371b68bf
4
+ data.tar.gz: 17866f6bfaf40d6e195c71655ac134430747e3690ce32c355036a8e30a62bbf1
5
5
  SHA512:
6
- metadata.gz: fee1727d038a4a74c11571ad040b86cb1d1b18bbeda4e9e3e59c46ae1a9d2eeab34d9660fbc9674e94601a14704d014e71bf782f61848c4e681bf3efd5e8f896
7
- data.tar.gz: 9f943406f882e4e4344870b05b3cc945bf03555095f0f581456b22a9f1b8596acc5091c72d6191c4e41ed0651e6c5a09a895c49b4ae3fc4a8550dc6f0fdd3c84
6
+ metadata.gz: ac9dad679a58246c1bd04d67de6812e9126f8f341edad4a72e842b80b759bcf2e020a2ad0c5bedd625eff861f22f0cbb224d4d2dc058a136d4c13087c4420248
7
+ data.tar.gz: b0f7285fd1e447c3f48e06d061aa441f64bb37de1952022e22e44835c3b549c639bceec13d9a690d0d14becb5eb724e1d2f31c05ea47a514ba2be57d9680de3b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,74 @@
1
+ ## [0.4.0] — 2026-07-27
2
+
3
+ ### Changed
4
+
5
+ - **`checkpoint_store:` renamed to `storage:`** — shorter, more general name
6
+ for the backend that persists checkpoint data for crash recovery.
7
+
8
+ ```ruby
9
+ # Before
10
+ MyGraph.call(input, checkpoint_store: RedisPool.new)
11
+ g.new(input, checkpoint_store: RedisPool.new)
12
+
13
+ # After
14
+ MyGraph.call(input, storage: RedisPool.new)
15
+ g.new(input, storage: RedisPool.new)
16
+ ```
17
+
18
+ ### Added
19
+
20
+ - **Class-level `storage`** — set once at the class level instead of passing
21
+ per-call. Works the same as `timeout`: per-call → graph class → global.
22
+
23
+ ```ruby
24
+ # Global default for all graphs
25
+ Ask::Graph.storage RedisPool.new
26
+
27
+ # Per-graph override
28
+ class MyGraph < Ask::Graph
29
+ storage PostgresStore.new
30
+ end
31
+
32
+ # Per-call override (overrides everything)
33
+ MyGraph.call(input, storage: InMemory.new)
34
+ ```
35
+
36
+ Falls back to `Ask::State::Memory.new` when nothing is configured.
37
+
38
+ ### Tested
39
+
40
+ - 70 tests, 92 assertions, 0 failures
41
+
42
+ ## [0.3.0] — 2026-07-27
43
+
44
+ ### Added
45
+
46
+ - **Class-level `timeout`** — set a default timeout for all steps in a graph.
47
+ Steps without an explicit `timeout:` option inherit the class default.
48
+
49
+ ```ruby
50
+ class MyGraph < Ask::Graph
51
+ timeout 30
52
+ step FastOp # uses 30s
53
+ step SlowOp, timeout: 120 # overrides
54
+ end
55
+ ```
56
+
57
+ - **Global default timeout** — `Ask::Graph.timeout 30` applies to all graphs
58
+ that don't set their own `timeout`. Resolution order: step option → graph
59
+ class → `Ask::Graph`.
60
+
61
+ ```ruby
62
+ Ask::Graph.timeout 30
63
+ ```
64
+
65
+ - **Child override and clearing** — child graphs can override or clear
66
+ (`timeout nil`) the parent's default.
67
+
68
+ ### Tested
69
+
70
+ - 62 tests, 83 assertions, 0 failures
71
+
1
72
  ## [0.2.0] — 2026-07-29
2
73
 
3
74
  ### Added
@@ -21,16 +21,19 @@ module Ask
21
21
  attr_reader :declarations, :store
22
22
 
23
23
  # @param declarations [Array<Hash>] step declarations
24
- # @param checkpoint_store [#set, #get, #delete] key-value store
24
+ # @param storage [#set, #get, #delete] key-value store for checkpoint data
25
25
  # @param hooks [Hash] lifecycle hook method names
26
26
  # @param graph_instance [Object] the graph instance (for hooks)
27
- def initialize(declarations, checkpoint_store: nil,
27
+ # @param default_timeout [Integer, nil] fallback timeout for steps with no explicit timeout
28
+ def initialize(declarations, storage: nil,
28
29
  hooks: { before_step: [], after_step: [], on_failure: [] },
29
- graph_instance: nil)
30
+ graph_instance: nil,
31
+ default_timeout: nil)
30
32
  @declarations = declarations
31
- @store = checkpoint_store
33
+ @store = storage
32
34
  @hooks = hooks
33
35
  @graph = graph_instance
36
+ @default_timeout = default_timeout
34
37
  @completed_steps = []
35
38
  end
36
39
 
@@ -90,6 +93,7 @@ module Ask
90
93
  end
91
94
 
92
95
  def run_with_timeout(decl, context, timeout_value)
96
+ timeout_value ||= @default_timeout
93
97
  if timeout_value
94
98
  ::Timeout.timeout(timeout_value) { execute_step(decl, context) }
95
99
  else
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  class Graph
5
- VERSION = "0.2.0"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
data/lib/ask/graph.rb CHANGED
@@ -46,6 +46,70 @@ module Ask
46
46
  subclass.instance_variable_set(:@lifecycle_hooks, lifecycle_hooks.dup)
47
47
  end
48
48
 
49
+ # --- Timeout ---
50
+
51
+ # Set or get the default timeout (in seconds) for steps in this graph.
52
+ # Steps without an explicit +timeout:+ option will inherit this value.
53
+ # Setting on {Ask::Graph} itself applies to all graphs that don't set
54
+ # their own default — a global default.
55
+ #
56
+ # @example Global default for all graphs
57
+ # Ask::Graph.timeout 30
58
+ #
59
+ # @example Per-graph override
60
+ # class MyGraph < Ask::Graph
61
+ # timeout 15
62
+ # step FastOp # uses 15s
63
+ # step SlowOp, timeout: 60 # overrides
64
+ # end
65
+ #
66
+ # @param seconds [Integer, nil] timeout in seconds, or nil to clear
67
+ # @return [Integer, nil] the current default timeout for this graph
68
+ def timeout(seconds = :not_set)
69
+ if seconds == :not_set
70
+ if instance_variable_defined?(:@timeout)
71
+ @timeout
72
+ elsif superclass.respond_to?(:timeout)
73
+ superclass.timeout
74
+ end
75
+ else
76
+ @timeout = seconds
77
+ end
78
+ end
79
+
80
+ # --- Storage ---
81
+
82
+ # Set or get the default storage backend for checkpoint data.
83
+ # The storage object must respond to +#set(key, value)+ and +#get(key)+.
84
+ #
85
+ # Setting on {Ask::Graph} itself applies to all graphs that don't set
86
+ # their own storage — a global default.
87
+ #
88
+ # @example Global default for all graphs
89
+ # Ask::Graph.storage RedisPool.new
90
+ #
91
+ # @example Per-graph override
92
+ # class MyGraph < Ask::Graph
93
+ # storage PostgresStore.new
94
+ # end
95
+ #
96
+ # @example Per-call override
97
+ # MyGraph.call(input, storage: InMemory.new)
98
+ #
99
+ # @param store [Object, nil] a backend that responds to +#set+ and +#get+
100
+ # @return [Object, nil] the current storage for this graph
101
+ def storage(store = :not_set)
102
+ if store == :not_set
103
+ if instance_variable_defined?(:@storage)
104
+ @storage
105
+ elsif superclass.respond_to?(:storage)
106
+ superclass.storage
107
+ end
108
+ else
109
+ @storage = store
110
+ end
111
+ end
112
+
49
113
  # --- Lifecycle hooks ---
50
114
 
51
115
  def lifecycle_hooks
@@ -111,8 +175,8 @@ module Ask
111
175
  end
112
176
 
113
177
  # Convenience: create instance and call.
114
- def call(input = nil, checkpoint_store: nil)
115
- new(input, checkpoint_store: checkpoint_store).call
178
+ def call(input = nil, storage: nil)
179
+ new(input, storage: storage).call
116
180
  end
117
181
  alias run call
118
182
 
@@ -132,14 +196,15 @@ module Ask
132
196
  end
133
197
  end
134
198
 
135
- def initialize(input = nil, checkpoint_store: nil)
199
+ def initialize(input = nil, storage: nil)
136
200
  @input = input
137
- store = checkpoint_store || Ask::State::Memory.new
201
+ store = storage || self.class.storage || Ask::State::Memory.new
138
202
  hooks = self.class.lifecycle_hooks
139
203
  @runner = Runner.new(self.class.declarations,
140
- checkpoint_store: store,
204
+ storage: store,
141
205
  hooks: hooks,
142
- graph_instance: self)
206
+ graph_instance: self,
207
+ default_timeout: self.class.timeout)
143
208
  @context = nil
144
209
  end
145
210
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-graph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto