simple_flow 0.1.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 +7 -0
- data/.envrc +1 -0
- data/.github/workflows/deploy-github-pages.yml +52 -0
- data/.rubocop.yml +57 -0
- data/CHANGELOG.md +4 -0
- data/COMMITS.md +196 -0
- data/LICENSE +21 -0
- data/README.md +481 -0
- data/Rakefile +15 -0
- data/benchmarks/parallel_vs_sequential.rb +98 -0
- data/benchmarks/pipeline_overhead.rb +130 -0
- data/docs/api/middleware.md +468 -0
- data/docs/api/parallel-step.md +363 -0
- data/docs/api/pipeline.md +382 -0
- data/docs/api/result.md +375 -0
- data/docs/concurrent/best-practices.md +687 -0
- data/docs/concurrent/introduction.md +246 -0
- data/docs/concurrent/parallel-steps.md +418 -0
- data/docs/concurrent/performance.md +481 -0
- data/docs/core-concepts/flow-control.md +452 -0
- data/docs/core-concepts/middleware.md +389 -0
- data/docs/core-concepts/overview.md +219 -0
- data/docs/core-concepts/pipeline.md +315 -0
- data/docs/core-concepts/result.md +168 -0
- data/docs/core-concepts/steps.md +391 -0
- data/docs/development/benchmarking.md +443 -0
- data/docs/development/contributing.md +380 -0
- data/docs/development/dagwood-concepts.md +435 -0
- data/docs/development/testing.md +514 -0
- data/docs/getting-started/examples.md +197 -0
- data/docs/getting-started/installation.md +62 -0
- data/docs/getting-started/quick-start.md +218 -0
- data/docs/guides/choosing-concurrency-model.md +441 -0
- data/docs/guides/complex-workflows.md +440 -0
- data/docs/guides/data-fetching.md +478 -0
- data/docs/guides/error-handling.md +635 -0
- data/docs/guides/file-processing.md +505 -0
- data/docs/guides/validation-patterns.md +496 -0
- data/docs/index.md +169 -0
- data/examples/.gitignore +3 -0
- data/examples/01_basic_pipeline.rb +112 -0
- data/examples/02_error_handling.rb +178 -0
- data/examples/03_middleware.rb +186 -0
- data/examples/04_parallel_automatic.rb +221 -0
- data/examples/05_parallel_explicit.rb +279 -0
- data/examples/06_real_world_ecommerce.rb +288 -0
- data/examples/07_real_world_etl.rb +277 -0
- data/examples/08_graph_visualization.rb +246 -0
- data/examples/09_pipeline_visualization.rb +266 -0
- data/examples/10_concurrency_control.rb +235 -0
- data/examples/11_sequential_dependencies.rb +243 -0
- data/examples/12_none_constant.rb +161 -0
- data/examples/README.md +374 -0
- data/examples/regression_test/01_basic_pipeline.txt +38 -0
- data/examples/regression_test/02_error_handling.txt +92 -0
- data/examples/regression_test/03_middleware.txt +61 -0
- data/examples/regression_test/04_parallel_automatic.txt +86 -0
- data/examples/regression_test/05_parallel_explicit.txt +80 -0
- data/examples/regression_test/06_real_world_ecommerce.txt +53 -0
- data/examples/regression_test/07_real_world_etl.txt +58 -0
- data/examples/regression_test/08_graph_visualization.txt +429 -0
- data/examples/regression_test/09_pipeline_visualization.txt +305 -0
- data/examples/regression_test/10_concurrency_control.txt +96 -0
- data/examples/regression_test/11_sequential_dependencies.txt +86 -0
- data/examples/regression_test/12_none_constant.txt +64 -0
- data/examples/regression_test.rb +105 -0
- data/lib/simple_flow/dependency_graph.rb +120 -0
- data/lib/simple_flow/dependency_graph_visualizer.rb +326 -0
- data/lib/simple_flow/middleware.rb +36 -0
- data/lib/simple_flow/parallel_executor.rb +80 -0
- data/lib/simple_flow/pipeline.rb +405 -0
- data/lib/simple_flow/result.rb +88 -0
- data/lib/simple_flow/step_tracker.rb +58 -0
- data/lib/simple_flow/version.rb +5 -0
- data/lib/simple_flow.rb +41 -0
- data/mkdocs.yml +146 -0
- data/pipeline_graph.dot +51 -0
- data/pipeline_graph.html +60 -0
- data/pipeline_graph.mmd +19 -0
- metadata +127 -0
data/examples/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# SimpleFlow Examples
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive examples demonstrating the capabilities of the SimpleFlow gem.
|
|
4
|
+
|
|
5
|
+
## Running the Examples
|
|
6
|
+
|
|
7
|
+
All examples are executable Ruby scripts. Make sure you've installed the gem dependencies first:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bundle install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then run any example:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ruby examples/01_basic_pipeline.rb
|
|
17
|
+
ruby examples/02_error_handling.rb
|
|
18
|
+
# ... etc
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Examples Overview
|
|
22
|
+
|
|
23
|
+
### 1. Basic Pipeline (`01_basic_pipeline.rb`)
|
|
24
|
+
|
|
25
|
+
**Demonstrates:**
|
|
26
|
+
- Sequential step execution
|
|
27
|
+
- Data transformation
|
|
28
|
+
- Context propagation through steps
|
|
29
|
+
- Simple computational pipelines
|
|
30
|
+
|
|
31
|
+
**Key concepts:**
|
|
32
|
+
- Using `step` to define pipeline stages
|
|
33
|
+
- `result.continue(value)` to pass data forward
|
|
34
|
+
- `result.with_context(key, value)` to track metadata
|
|
35
|
+
|
|
36
|
+
**Run time:** ~2 seconds
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### 2. Error Handling (`02_error_handling.rb`)
|
|
41
|
+
|
|
42
|
+
**Demonstrates:**
|
|
43
|
+
- Input validation with `halt`
|
|
44
|
+
- Error accumulation across steps
|
|
45
|
+
- Conditional flow control
|
|
46
|
+
- Role-based processing
|
|
47
|
+
|
|
48
|
+
**Key concepts:**
|
|
49
|
+
- `result.halt` to stop execution
|
|
50
|
+
- `result.with_error(key, message)` to track errors
|
|
51
|
+
- Checking `result.continue?` to see if pipeline should proceed
|
|
52
|
+
- Early termination prevents later steps from running
|
|
53
|
+
|
|
54
|
+
**Run time:** ~1 second
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### 3. Middleware (`03_middleware.rb`)
|
|
59
|
+
|
|
60
|
+
**Demonstrates:**
|
|
61
|
+
- Built-in logging middleware
|
|
62
|
+
- Built-in instrumentation middleware
|
|
63
|
+
- Stacking multiple middleware
|
|
64
|
+
- Custom middleware (retry logic, authentication)
|
|
65
|
+
|
|
66
|
+
**Key concepts:**
|
|
67
|
+
- `use_middleware ClassName, options` to add middleware
|
|
68
|
+
- Middleware wraps all steps in the pipeline
|
|
69
|
+
- Custom middleware by implementing `.new(callable, **options)` and `#call(result)`
|
|
70
|
+
- Middleware execution order (reverse of declaration)
|
|
71
|
+
|
|
72
|
+
**Run time:** ~3 seconds
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### 4. Automatic Parallel Discovery (`04_parallel_automatic.rb`)
|
|
77
|
+
|
|
78
|
+
**Demonstrates:**
|
|
79
|
+
- Named steps with dependency declarations
|
|
80
|
+
- Automatic dependency graph construction
|
|
81
|
+
- Parallel execution of independent steps
|
|
82
|
+
- Complex multi-level dependency graphs
|
|
83
|
+
- Dependency graph visualization
|
|
84
|
+
|
|
85
|
+
**Key concepts:**
|
|
86
|
+
- `step :name, callable, depends_on: [...]` for named steps
|
|
87
|
+
- `call_parallel` to execute with automatic parallelism
|
|
88
|
+
- Steps with satisfied dependencies run concurrently
|
|
89
|
+
- Context and error merging from parallel steps
|
|
90
|
+
|
|
91
|
+
**Run time:** ~1-2 seconds (with async), ~3-4 seconds (without)
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
### 5. Explicit Parallel Blocks (`05_parallel_explicit.rb`)
|
|
96
|
+
|
|
97
|
+
**Demonstrates:**
|
|
98
|
+
- Explicit `parallel do...end` blocks
|
|
99
|
+
- Multiple parallel blocks in one pipeline
|
|
100
|
+
- Mixing sequential and parallel execution
|
|
101
|
+
- Error handling in parallel blocks
|
|
102
|
+
- Performance comparison vs sequential
|
|
103
|
+
|
|
104
|
+
**Key concepts:**
|
|
105
|
+
- `parallel do ... end` to define concurrent execution
|
|
106
|
+
- All steps in a parallel block run simultaneously
|
|
107
|
+
- Halting in any parallel step stops the pipeline
|
|
108
|
+
- Contexts from all parallel steps are merged
|
|
109
|
+
|
|
110
|
+
**Run time:** ~1 second (with async), ~2 seconds (without)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### 6. Real-World: E-commerce Order Processing (`06_real_world_ecommerce.rb`)
|
|
115
|
+
|
|
116
|
+
**Demonstrates:**
|
|
117
|
+
- Complete e-commerce order pipeline
|
|
118
|
+
- Integration with multiple services (inventory, payment, shipping)
|
|
119
|
+
- Parallel validation and data fetching
|
|
120
|
+
- Error handling at each stage
|
|
121
|
+
- Notifications in parallel
|
|
122
|
+
|
|
123
|
+
**Pipeline flow:**
|
|
124
|
+
1. Validate order
|
|
125
|
+
2. Check inventory + Calculate shipping (parallel)
|
|
126
|
+
3. Calculate totals
|
|
127
|
+
4. Process payment
|
|
128
|
+
5. Reserve inventory
|
|
129
|
+
6. Create shipment
|
|
130
|
+
7. Send email + SMS (parallel)
|
|
131
|
+
8. Finalize order
|
|
132
|
+
|
|
133
|
+
**Key concepts:**
|
|
134
|
+
- Real-world service integration patterns
|
|
135
|
+
- Dependency management for complex workflows
|
|
136
|
+
- Transaction-like behavior with halt on failure
|
|
137
|
+
- Parallel execution for independent operations
|
|
138
|
+
|
|
139
|
+
**Run time:** ~1-2 seconds
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### 7. Real-World: Data ETL Pipeline (`07_real_world_etl.rb`)
|
|
144
|
+
|
|
145
|
+
**Demonstrates:**
|
|
146
|
+
- Extract, Transform, Load (ETL) pattern
|
|
147
|
+
- Multi-source data extraction in parallel
|
|
148
|
+
- Data transformation and normalization
|
|
149
|
+
- Data aggregation and analytics
|
|
150
|
+
- Data quality validation
|
|
151
|
+
- Output preparation
|
|
152
|
+
|
|
153
|
+
**Pipeline flow:**
|
|
154
|
+
1. **Extract:** Fetch users + orders + products (parallel)
|
|
155
|
+
2. **Transform:** Clean/normalize all data (parallel)
|
|
156
|
+
3. **Aggregate:** Compute statistics (parallel)
|
|
157
|
+
4. **Validate:** Check data quality
|
|
158
|
+
5. **Load:** Prepare final output
|
|
159
|
+
|
|
160
|
+
**Key concepts:**
|
|
161
|
+
- Parallel data loading from multiple sources
|
|
162
|
+
- Independent transformation pipelines
|
|
163
|
+
- Analytics computation from joined data
|
|
164
|
+
- Validation before output
|
|
165
|
+
- Metadata tracking
|
|
166
|
+
|
|
167
|
+
**Run time:** ~1-2 seconds
|
|
168
|
+
|
|
169
|
+
**Optional:** Run with `--save` flag to export JSON output:
|
|
170
|
+
```bash
|
|
171
|
+
ruby examples/07_real_world_etl.rb --save
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### 8. Graph Visualization (`08_graph_visualization.rb`)
|
|
177
|
+
|
|
178
|
+
**Demonstrates:**
|
|
179
|
+
- Visualizing dependency graphs
|
|
180
|
+
- ASCII art terminal output
|
|
181
|
+
- Exporting to Graphviz DOT format
|
|
182
|
+
- Exporting to Mermaid diagram format
|
|
183
|
+
- Generating interactive HTML visualizations
|
|
184
|
+
- Execution plan analysis
|
|
185
|
+
- Graph analytics and statistics
|
|
186
|
+
|
|
187
|
+
**Visualization formats:**
|
|
188
|
+
- **ASCII** - Terminal-friendly text representation
|
|
189
|
+
- **DOT** - Graphviz format for PNG/SVG/PDF generation
|
|
190
|
+
- **Mermaid** - Modern diagram syntax for web
|
|
191
|
+
- **HTML** - Interactive browser-based visualization
|
|
192
|
+
- **Execution Plan** - Detailed performance analysis
|
|
193
|
+
|
|
194
|
+
**Key concepts:**
|
|
195
|
+
- Understanding dependency relationships
|
|
196
|
+
- Identifying parallel execution opportunities
|
|
197
|
+
- Visualizing pipeline structure
|
|
198
|
+
- Analyzing graph performance characteristics
|
|
199
|
+
- Exporting for documentation
|
|
200
|
+
|
|
201
|
+
**Run time:** ~1 second
|
|
202
|
+
|
|
203
|
+
**Generates files:**
|
|
204
|
+
- `ecommerce_graph.dot` - For Graphviz
|
|
205
|
+
- `ecommerce_graph.mmd` - For Mermaid
|
|
206
|
+
- `ecommerce_graph.html` - Interactive visualization
|
|
207
|
+
|
|
208
|
+
**To generate images:**
|
|
209
|
+
```bash
|
|
210
|
+
# Install Graphviz first (brew install graphviz / apt-get install graphviz)
|
|
211
|
+
dot -Tpng ecommerce_graph.dot -o ecommerce_graph.png
|
|
212
|
+
dot -Tsvg ecommerce_graph.dot -o ecommerce_graph.svg
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### 9. Pipeline Visualization (Direct) (`09_pipeline_visualization.rb`) ⭐ RECOMMENDED
|
|
218
|
+
|
|
219
|
+
**Demonstrates:**
|
|
220
|
+
- **Direct visualization from pipelines** (no manual graph creation!)
|
|
221
|
+
- Calling `pipeline.visualize_ascii` directly
|
|
222
|
+
- Exporting with `pipeline.visualize_dot`, `pipeline.visualize_mermaid`
|
|
223
|
+
- Getting execution plan with `pipeline.execution_plan`
|
|
224
|
+
- Checking if pipeline can be visualized
|
|
225
|
+
- Comparing different pipeline structures
|
|
226
|
+
|
|
227
|
+
**Key advantage:**
|
|
228
|
+
This example shows the **recommended approach** - visualizing pipelines directly without manually recreating dependency structures. The pipeline already knows its dependencies, so you can simply call visualization methods on it.
|
|
229
|
+
|
|
230
|
+
**API methods:**
|
|
231
|
+
- `pipeline.visualize_ascii()` - Terminal visualization
|
|
232
|
+
- `pipeline.visualize_dot()` - Graphviz export
|
|
233
|
+
- `pipeline.visualize_mermaid()` - Mermaid export
|
|
234
|
+
- `pipeline.execution_plan()` - Performance analysis
|
|
235
|
+
- `pipeline.dependency_graph()` - Get graph object
|
|
236
|
+
- `pipeline.visualize()` - Get visualizer object
|
|
237
|
+
|
|
238
|
+
**Run time:** ~1 second
|
|
239
|
+
|
|
240
|
+
**Note:** Only works with pipelines that have named steps (using `step :name, callable, depends_on: [...]` or `depends_on: :none`). Unnamed steps cannot be auto-visualized.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### 10. Concurrency Control (`10_concurrency_control.rb`)
|
|
245
|
+
|
|
246
|
+
**Demonstrates:**
|
|
247
|
+
- Per-pipeline concurrency model selection
|
|
248
|
+
- Forcing threads vs async for different pipelines
|
|
249
|
+
- Mixing concurrency models in the same application
|
|
250
|
+
- Auto-detection behavior
|
|
251
|
+
- Error handling for unavailable concurrency models
|
|
252
|
+
|
|
253
|
+
**Key concepts:**
|
|
254
|
+
- `Pipeline.new(concurrency: :threads)` - Force thread-based execution
|
|
255
|
+
- `Pipeline.new(concurrency: :async)` - Require async gem (raises if unavailable)
|
|
256
|
+
- `Pipeline.new(concurrency: :auto)` - Auto-detect (default)
|
|
257
|
+
- Different pipelines can use different models in the same app
|
|
258
|
+
|
|
259
|
+
**Run time:** ~1-2 seconds
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### 11. Sequential Dependencies (`11_sequential_dependencies.rb`)
|
|
264
|
+
|
|
265
|
+
**Demonstrates:**
|
|
266
|
+
- Sequential step execution with automatic dependencies
|
|
267
|
+
- Pipeline short-circuiting when a step halts
|
|
268
|
+
- How unnamed steps depend on previous step's success
|
|
269
|
+
- Error propagation through the pipeline
|
|
270
|
+
- Comparison with parallel execution
|
|
271
|
+
|
|
272
|
+
**Key concepts:**
|
|
273
|
+
- Unnamed steps automatically depend on previous step
|
|
274
|
+
- `result.halt` stops the entire pipeline immediately
|
|
275
|
+
- Subsequent steps are never executed after a halt
|
|
276
|
+
- Errors accumulate and propagate through the result
|
|
277
|
+
|
|
278
|
+
**Run time:** ~1 second
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### 12. Reserved Dependency Symbols (`12_none_constant.rb`)
|
|
283
|
+
|
|
284
|
+
**Demonstrates:**
|
|
285
|
+
- Using `:none` symbol for cleaner "no dependencies" syntax
|
|
286
|
+
- Using `:nothing` as an alternative
|
|
287
|
+
- Comparison with empty array `[]` syntax
|
|
288
|
+
- Multiple independent root steps
|
|
289
|
+
- Filtering reserved symbols from dependency arrays
|
|
290
|
+
|
|
291
|
+
**Key concepts:**
|
|
292
|
+
- `depends_on: :none` is equivalent to `depends_on: []`
|
|
293
|
+
- More readable and semantic than empty array
|
|
294
|
+
- `:none` and `:nothing` are reserved symbols (cannot be step names)
|
|
295
|
+
- Symbols are automatically filtered from dependency arrays
|
|
296
|
+
|
|
297
|
+
**Run time:** ~1 second
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Async Gem Availability
|
|
302
|
+
|
|
303
|
+
All parallel examples will automatically use the `async` gem if available for true concurrent execution. If not available, they fall back to sequential execution.
|
|
304
|
+
|
|
305
|
+
Check async availability:
|
|
306
|
+
```ruby
|
|
307
|
+
pipeline = SimpleFlow::Pipeline.new
|
|
308
|
+
puts pipeline.async_available? # => true or false
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Learning Path
|
|
312
|
+
|
|
313
|
+
Recommended order for learning:
|
|
314
|
+
|
|
315
|
+
1. Start with `01_basic_pipeline.rb` to understand core concepts
|
|
316
|
+
2. Move to `02_error_handling.rb` for flow control
|
|
317
|
+
3. Explore `03_middleware.rb` for cross-cutting concerns
|
|
318
|
+
4. Learn parallel execution with `04_parallel_automatic.rb` and `05_parallel_explicit.rb`
|
|
319
|
+
5. See real-world applications in `06_real_world_ecommerce.rb` and `07_real_world_etl.rb`
|
|
320
|
+
|
|
321
|
+
## Customization
|
|
322
|
+
|
|
323
|
+
All examples are designed to be modified. Try:
|
|
324
|
+
|
|
325
|
+
- Adding your own steps to pipelines
|
|
326
|
+
- Creating custom middleware
|
|
327
|
+
- Changing dependency graphs
|
|
328
|
+
- Adding more error handling
|
|
329
|
+
- Integrating with real external services
|
|
330
|
+
|
|
331
|
+
## Performance Notes
|
|
332
|
+
|
|
333
|
+
- **Parallel execution** is most beneficial for I/O-bound operations (API calls, DB queries, file operations)
|
|
334
|
+
- **Sequential execution** may be faster for CPU-bound tasks due to Ruby's GIL
|
|
335
|
+
- Run examples multiple times to see consistent timing
|
|
336
|
+
- Actual speedup depends on system resources and async gem availability
|
|
337
|
+
|
|
338
|
+
## Troubleshooting
|
|
339
|
+
|
|
340
|
+
**Async gem not loading:**
|
|
341
|
+
```bash
|
|
342
|
+
bundle install
|
|
343
|
+
gem install async
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Permission errors on example files:**
|
|
347
|
+
```bash
|
|
348
|
+
chmod +x examples/*.rb
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Examples run sequentially despite async gem:**
|
|
352
|
+
- Check that async gem is properly installed
|
|
353
|
+
- Verify with `pipeline.async_available?`
|
|
354
|
+
|
|
355
|
+
## Additional Resources
|
|
356
|
+
|
|
357
|
+
- [SimpleFlow README](../README.md) - Full gem documentation
|
|
358
|
+
- [Test Suite](../test/) - More usage examples
|
|
359
|
+
- [Source Code](../lib/simple_flow/) - Implementation details
|
|
360
|
+
|
|
361
|
+
## Contributing Examples
|
|
362
|
+
|
|
363
|
+
Have a great use case? Consider contributing an example:
|
|
364
|
+
|
|
365
|
+
1. Follow the existing naming convention (`NN_description.rb`)
|
|
366
|
+
2. Include clear comments and output
|
|
367
|
+
3. Demonstrate a specific feature or pattern
|
|
368
|
+
4. Keep examples self-contained and runnable
|
|
369
|
+
5. Add an entry to this README
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
**Questions or Issues?**
|
|
374
|
+
Open an issue at: https://github.com/MadBomber/simple_flow/issues
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
============================================================
|
|
2
|
+
Basic Pipeline Example
|
|
3
|
+
============================================================
|
|
4
|
+
|
|
5
|
+
Example 1: Data Transformation Pipeline
|
|
6
|
+
------------------------------------------------------------
|
|
7
|
+
Step 1: Trimming whitespace
|
|
8
|
+
Step 2: Converting to uppercase
|
|
9
|
+
Step 3: Adding greeting
|
|
10
|
+
Input: ' world '
|
|
11
|
+
Output: 'Hello, WORLD!'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Example 2: Numerical Computation Pipeline
|
|
15
|
+
------------------------------------------------------------
|
|
16
|
+
Step 1: Add 10
|
|
17
|
+
Step 2: Multiply by 2
|
|
18
|
+
Step 3: Subtract 5
|
|
19
|
+
Input: 5
|
|
20
|
+
Output: 25
|
|
21
|
+
Formula: (5 + 10) * 2 - 5 = 25
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Example 3: Context Propagation
|
|
25
|
+
------------------------------------------------------------
|
|
26
|
+
Step 1: Recording start time
|
|
27
|
+
Step 2: Processing data
|
|
28
|
+
Step 3: Recording completion
|
|
29
|
+
Result: PROCESSING
|
|
30
|
+
Context:
|
|
31
|
+
started_at: 2001-09-11 07:00:00 -0500
|
|
32
|
+
processed_at: 2001-09-11 07:00:00 -0500
|
|
33
|
+
completed_at: 2001-09-11 07:00:00 -0500
|
|
34
|
+
steps_executed: 3
|
|
35
|
+
|
|
36
|
+
============================================================
|
|
37
|
+
Basic pipeline examples completed!
|
|
38
|
+
============================================================
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
============================================================
|
|
2
|
+
Error Handling and Flow Control
|
|
3
|
+
============================================================
|
|
4
|
+
|
|
5
|
+
Example 1: Input Validation with Halt
|
|
6
|
+
------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
Test 1: Valid age (21)
|
|
9
|
+
Step 1: Validating age is numeric
|
|
10
|
+
Step 2: Validating age is positive
|
|
11
|
+
Step 3: Checking minimum age
|
|
12
|
+
Step 4: Processing valid age
|
|
13
|
+
Continue? true
|
|
14
|
+
Result: Approved for age 21
|
|
15
|
+
Errors: {}
|
|
16
|
+
|
|
17
|
+
Test 2: Invalid age (15)
|
|
18
|
+
Step 1: Validating age is numeric
|
|
19
|
+
Step 2: Validating age is positive
|
|
20
|
+
Step 3: Checking minimum age
|
|
21
|
+
Continue? false
|
|
22
|
+
Result: 15
|
|
23
|
+
Errors: {validation: ["Must be 18 or older"]}
|
|
24
|
+
|
|
25
|
+
Test 3: Negative age (-5)
|
|
26
|
+
Step 1: Validating age is numeric
|
|
27
|
+
Step 2: Validating age is positive
|
|
28
|
+
Continue? false
|
|
29
|
+
Result: -5
|
|
30
|
+
Errors: {validation: ["Age cannot be negative"]}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Example 2: Error Accumulation
|
|
34
|
+
------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
Test 1: Weak password
|
|
37
|
+
Step 1: Checking password length
|
|
38
|
+
Step 2: Checking for uppercase letters
|
|
39
|
+
Step 3: Checking for numbers
|
|
40
|
+
Step 4: Final validation
|
|
41
|
+
Continue? false
|
|
42
|
+
Result: {username: "john", password: "weak"}
|
|
43
|
+
Errors: {password: ["Password must be at least 8 characters", "Password must contain uppercase letters", "Password must contain numbers"]}
|
|
44
|
+
|
|
45
|
+
Test 2: Strong password
|
|
46
|
+
Step 1: Checking password length
|
|
47
|
+
Step 2: Checking for uppercase letters
|
|
48
|
+
Step 3: Checking for numbers
|
|
49
|
+
Step 4: Final validation
|
|
50
|
+
Step 5: Creating account (only runs if valid)
|
|
51
|
+
Continue? true
|
|
52
|
+
Result: Account created for jane
|
|
53
|
+
Errors: {}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Example 3: Conditional Processing
|
|
57
|
+
------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
Testing role: admin
|
|
60
|
+
Step 1: Checking user role
|
|
61
|
+
Step 2: Role-based processing
|
|
62
|
+
Step 3: Generating access token
|
|
63
|
+
Continue? true
|
|
64
|
+
Result: Token granted with permissions: read, write, delete
|
|
65
|
+
Permissions: [:read, :write, :delete]
|
|
66
|
+
|
|
67
|
+
Testing role: editor
|
|
68
|
+
Step 1: Checking user role
|
|
69
|
+
Step 2: Role-based processing
|
|
70
|
+
Step 3: Generating access token
|
|
71
|
+
Continue? true
|
|
72
|
+
Result: Token granted with permissions: read, write
|
|
73
|
+
Permissions: [:read, :write]
|
|
74
|
+
|
|
75
|
+
Testing role: viewer
|
|
76
|
+
Step 1: Checking user role
|
|
77
|
+
Step 2: Role-based processing
|
|
78
|
+
Step 3: Generating access token
|
|
79
|
+
Continue? true
|
|
80
|
+
Result: Token granted with permissions: read
|
|
81
|
+
Permissions: [:read]
|
|
82
|
+
|
|
83
|
+
Testing role: unknown
|
|
84
|
+
Step 1: Checking user role
|
|
85
|
+
Step 2: Role-based processing
|
|
86
|
+
Continue? false
|
|
87
|
+
Result: {role: :unknown}
|
|
88
|
+
Errors: {auth: ["Unknown role: unknown"]}
|
|
89
|
+
|
|
90
|
+
============================================================
|
|
91
|
+
Error handling examples completed!
|
|
92
|
+
============================================================
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
============================================================
|
|
2
|
+
Middleware Examples
|
|
3
|
+
============================================================
|
|
4
|
+
|
|
5
|
+
Example 1: Logging Middleware
|
|
6
|
+
------------------------------------------------------------
|
|
7
|
+
Executing pipeline with logging middleware:
|
|
8
|
+
I, [2001-09-11T07:00:00.000051 #62312] INFO -- : Before call
|
|
9
|
+
I, [2001-09-11T07:00:00.000083 #62312] INFO -- : After call
|
|
10
|
+
I, [2001-09-11T07:00:00.000099 #62312] INFO -- : Before call
|
|
11
|
+
I, [2001-09-11T07:00:00.000109 #62312] INFO -- : After call
|
|
12
|
+
Final result: 20
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Example 2: Instrumentation Middleware
|
|
16
|
+
------------------------------------------------------------
|
|
17
|
+
Executing pipeline with instrumentation middleware:
|
|
18
|
+
Instrumentation: demo-key-123 took 0.012575s
|
|
19
|
+
Instrumentation: demo-key-123 took 0.022543s
|
|
20
|
+
Final result: Processed: DATA
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Example 3: Stacked Middleware
|
|
24
|
+
------------------------------------------------------------
|
|
25
|
+
Executing pipeline with multiple middleware:
|
|
26
|
+
I, [2001-09-11T07:00:00.035360 #62312] INFO -- : Before call
|
|
27
|
+
I, [2001-09-11T07:00:00.035377 #62312] INFO -- : After call
|
|
28
|
+
Instrumentation: stacked-demo took 4.3e-05s
|
|
29
|
+
I, [2001-09-11T07:00:00.035405 #62312] INFO -- : Before call
|
|
30
|
+
I, [2001-09-11T07:00:00.035414 #62312] INFO -- : After call
|
|
31
|
+
Instrumentation: stacked-demo took 2.4e-05s
|
|
32
|
+
Final result: 45
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Example 4: Custom Retry Middleware
|
|
36
|
+
------------------------------------------------------------
|
|
37
|
+
Executing pipeline with retry middleware:
|
|
38
|
+
Attempt 1 of 3
|
|
39
|
+
Failed (Temporary failure), retrying...
|
|
40
|
+
Attempt 2 of 3
|
|
41
|
+
Final result: Success on attempt 2
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
Example 5: Custom Authentication Middleware
|
|
45
|
+
------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
Test 1: Admin user
|
|
48
|
+
Access granted for admin
|
|
49
|
+
Continue? true
|
|
50
|
+
Result: Sensitive admin operation completed
|
|
51
|
+
Errors: {}
|
|
52
|
+
|
|
53
|
+
Test 2: Regular user
|
|
54
|
+
Access denied: requires admin, got user
|
|
55
|
+
Continue? false
|
|
56
|
+
Result: {role: :user}
|
|
57
|
+
Errors: {auth: ["Unauthorized: requires admin role"]}
|
|
58
|
+
|
|
59
|
+
============================================================
|
|
60
|
+
Middleware examples completed!
|
|
61
|
+
============================================================
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
============================================================
|
|
2
|
+
Automatic Parallel Discovery
|
|
3
|
+
============================================================
|
|
4
|
+
|
|
5
|
+
✓ Async gem is available - will use fiber-based concurrency
|
|
6
|
+
|
|
7
|
+
Example 1: Basic Parallel Execution
|
|
8
|
+
------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
[07:00:00.000] Fetching user...
|
|
11
|
+
[07:00:00.105] Fetching orders...
|
|
12
|
+
[07:00:00.105] Fetching products...
|
|
13
|
+
[07:00:00.206] Calculating total...
|
|
14
|
+
|
|
15
|
+
Result: Total: 3 orders, 3 products
|
|
16
|
+
User: {id: 123, name: "John Doe"}
|
|
17
|
+
Orders: [1, 2, 3]
|
|
18
|
+
Products: [:a, :b, :c]
|
|
19
|
+
Execution time: 206.3ms
|
|
20
|
+
(Should be ~200ms with parallel, ~400ms sequential)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Example 2: Complex Dependency Graph
|
|
24
|
+
------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
Dependency graph structure:
|
|
27
|
+
Level 1: validate_input
|
|
28
|
+
Level 2: check_inventory, check_pricing, check_shipping (parallel)
|
|
29
|
+
Level 3: calculate_discount
|
|
30
|
+
Level 4: finalize_order
|
|
31
|
+
|
|
32
|
+
[Level 1] Validating input...
|
|
33
|
+
[Level 2] Checking inventory...
|
|
34
|
+
[Level 2] Checking pricing...
|
|
35
|
+
[Level 2] Checking shipping...
|
|
36
|
+
[Level 3] Calculating discount...
|
|
37
|
+
[Level 4] Finalizing order...
|
|
38
|
+
|
|
39
|
+
Result: Order total: $100.0
|
|
40
|
+
Context: {validated: true, inventory: :available, price: 100, shipping: 10, discount: 10.0}
|
|
41
|
+
Execution time: 160.32ms
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
Example 3: Dependency Graph Analysis
|
|
45
|
+
------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
Dependencies:
|
|
48
|
+
fetch_user: (none)
|
|
49
|
+
fetch_orders: fetch_user
|
|
50
|
+
fetch_products: fetch_user
|
|
51
|
+
fetch_reviews: fetch_user
|
|
52
|
+
calculate_stats: fetch_orders, fetch_products
|
|
53
|
+
generate_report: calculate_stats, fetch_reviews
|
|
54
|
+
|
|
55
|
+
Sequential order:
|
|
56
|
+
fetch_user → fetch_orders → fetch_products → fetch_reviews → calculate_stats → generate_report
|
|
57
|
+
|
|
58
|
+
Parallel execution groups:
|
|
59
|
+
Group 1: fetch_user
|
|
60
|
+
Group 2: fetch_orders, fetch_products, fetch_reviews
|
|
61
|
+
Group 3: calculate_stats
|
|
62
|
+
Group 4: generate_report
|
|
63
|
+
|
|
64
|
+
Execution strategy:
|
|
65
|
+
• fetch_user runs first (no dependencies)
|
|
66
|
+
• fetch_orders, fetch_products, fetch_reviews run in parallel
|
|
67
|
+
• calculate_stats waits for orders and products
|
|
68
|
+
• generate_report waits for stats and reviews
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
Example 4: Error Handling in Parallel Execution
|
|
72
|
+
------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
Task A: Processing...
|
|
75
|
+
Task B: Processing...
|
|
76
|
+
Task C: Processing...
|
|
77
|
+
|
|
78
|
+
Result:
|
|
79
|
+
Continue? false
|
|
80
|
+
Errors: {task_b: ["Task B encountered an error"]}
|
|
81
|
+
Context: {}
|
|
82
|
+
Note: Pipeline halted when task_b failed, preventing final_step
|
|
83
|
+
|
|
84
|
+
============================================================
|
|
85
|
+
Automatic parallel discovery examples completed!
|
|
86
|
+
============================================================
|