fractor 0.1.9 → 0.1.10

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: 9b4ea06ce5fb4dc056cd294dcadeac07cca24610a0b995e5f910b3ef0075e0ea
4
- data.tar.gz: 1adc8b962143e4713259b18c5545ab39ee0a62b11db5880b0389ff64449a27b8
3
+ metadata.gz: 22b2448a14f44c78c6b4970d9529aa9e88257ff63423be18e57dd87290f5247b
4
+ data.tar.gz: 27a514ab149f2115e5e53fe0c4a3199d09adeb355789ce21ff85ab93b8cb1891
5
5
  SHA512:
6
- metadata.gz: 31800cb4767762f1bdd1fec315cda164fd5effb3fd72bb327b4a30788ac41b2b2cd0ec3bcf2548e82fe69ccf97150007222e81c875bcb5f78c01d4e28162ef03
7
- data.tar.gz: 728316725154c5fde32f2bb8fb6ab584b26814ad463af43c4928a333083ed34e6d66dc781c6edad82128644f0f6b6197c31303aa6353ec586aeaa81212dd911d
6
+ metadata.gz: 2da27fec2e527d266dc85e3fc29fd646740e76c8b9e77a5c6171bd79fa6054f4a0bae79fc72d99aa4ca683a5fcf5a9f079aeef35123ce4e25de846948ba9a991
7
+ data.tar.gz: 7d01bbb10b527954f8afdb1dd9e9e8858342a71fddf3734bbc178a4ab0c227e9b69ee4f336b3f37016a17da4ea1e69c1dc65a48fa31de73cef6469bf413e851e
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-01-22 09:15:54 UTC using RuboCop version 1.82.1.
3
+ # on 2026-01-27 14:55:44 UTC using RuboCop version 1.82.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,80 +11,13 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'fractor.gemspec'
13
13
 
14
- # Offense count: 1
15
- # This cop supports safe autocorrection (--autocorrect).
16
- # Configuration parameters: EnforcedStyle, IndentationWidth.
17
- # SupportedStyles: with_first_argument, with_fixed_indentation
18
- Layout/ArgumentAlignment:
19
- Exclude:
20
- - 'lib/fractor/queue_persister.rb'
21
-
22
- # Offense count: 1
23
- # This cop supports safe autocorrection (--autocorrect).
24
- # Configuration parameters: EnforcedStyle, IndentationWidth.
25
- # SupportedStyles: with_first_element, with_fixed_indentation
26
- Layout/ArrayAlignment:
27
- Exclude:
28
- - 'lib/fractor/queue_persister.rb'
29
-
30
- # Offense count: 2
31
- # This cop supports safe autocorrection (--autocorrect).
32
- # Configuration parameters: IndentationWidth.
33
- Layout/AssignmentIndentation:
34
- Exclude:
35
- - 'lib/fractor/queue_persister.rb'
36
- - 'lib/fractor/result_cache.rb'
37
-
38
- # Offense count: 1
39
- # This cop supports safe autocorrection (--autocorrect).
40
- Layout/ClosingParenthesisIndentation:
41
- Exclude:
42
- - 'spec/fractor/persistent_work_queue_spec.rb'
43
-
44
- # Offense count: 1
45
- # This cop supports safe autocorrection (--autocorrect).
46
- # Configuration parameters: EnforcedStyle, IndentationWidth.
47
- # SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
48
- Layout/FirstArgumentIndentation:
49
- Exclude:
50
- - 'spec/fractor/persistent_work_queue_spec.rb'
51
-
52
- # Offense count: 2
53
- # This cop supports safe autocorrection (--autocorrect).
54
- # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
55
- # SupportedHashRocketStyles: key, separator, table
56
- # SupportedColonStyles: key, separator, table
57
- # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
58
- Layout/HashAlignment:
59
- Exclude:
60
- - 'spec/fractor/persistent_work_queue_spec.rb'
61
- - 'spec/fractor/work_timeout_spec.rb'
62
-
63
- # Offense count: 470
14
+ # Offense count: 498
64
15
  # This cop supports safe autocorrection (--autocorrect).
65
16
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
66
17
  # URISchemes: http, https
67
18
  Layout/LineLength:
68
19
  Enabled: false
69
20
 
70
- # Offense count: 1
71
- # This cop supports safe autocorrection (--autocorrect).
72
- # Configuration parameters: EnforcedStyle.
73
- # SupportedStyles: symmetrical, new_line, same_line
74
- Layout/MultilineMethodCallBraceLayout:
75
- Exclude:
76
- - 'spec/fractor/persistent_work_queue_spec.rb'
77
-
78
- # Offense count: 6
79
- # This cop supports safe autocorrection (--autocorrect).
80
- # Configuration parameters: AllowInHeredoc.
81
- Layout/TrailingWhitespace:
82
- Exclude:
83
- - 'lib/fractor/queue_persister.rb'
84
- - 'lib/fractor/result_cache.rb'
85
- - 'spec/fractor/persistent_work_queue_spec.rb'
86
- - 'spec/fractor/work_timeout_spec.rb'
87
-
88
21
  # Offense count: 1
89
22
  Lint/BinaryOperatorWithIdenticalOperands:
90
23
  Exclude:
@@ -143,7 +76,13 @@ Lint/UnusedMethodArgument:
143
76
  - 'lib/fractor/workflow.rb'
144
77
  - 'lib/fractor/wrapped_ractor3.rb'
145
78
 
146
- # Offense count: 89
79
+ # Offense count: 1
80
+ # This cop supports safe autocorrection (--autocorrect).
81
+ Lint/UselessAssignment:
82
+ Exclude:
83
+ - 'lib/fractor/wrapped_ractor.rb'
84
+
85
+ # Offense count: 92
147
86
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
148
87
  Metrics/AbcSize:
149
88
  Enabled: false
@@ -159,17 +98,17 @@ Metrics/BlockLength:
159
98
  Metrics/CyclomaticComplexity:
160
99
  Enabled: false
161
100
 
162
- # Offense count: 149
101
+ # Offense count: 155
163
102
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
164
103
  Metrics/MethodLength:
165
104
  Max: 122
166
105
 
167
- # Offense count: 9
106
+ # Offense count: 10
168
107
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
169
108
  Metrics/ParameterLists:
170
109
  Max: 9
171
110
 
172
- # Offense count: 49
111
+ # Offense count: 50
173
112
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
174
113
  Metrics/PerceivedComplexity:
175
114
  Enabled: false
@@ -193,17 +132,14 @@ Naming/PredicatePrefix:
193
132
  - '../../../.cache/rubocop_cache/spec/**/*'
194
133
  - 'spec/support/workflow_helpers.rb'
195
134
 
196
- # Offense count: 9
135
+ # Offense count: 6
197
136
  # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
198
137
  # SupportedStyles: snake_case, normalcase, non_integer
199
138
  # AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
200
139
  Naming/VariableNumber:
201
140
  Exclude:
202
141
  - 'lib/fractor/error_statistics.rb'
203
- - 'lib/fractor/main_loop_handler.rb'
204
142
  - 'lib/fractor/main_loop_handler4.rb'
205
- - 'lib/fractor/supervisor.rb'
206
- - 'lib/fractor/wrapped_ractor.rb'
207
143
  - 'spec/examples/error_reporting_spec.rb'
208
144
  - 'spec/fractor/workflow/retry_orchestrator_spec.rb'
209
145
 
@@ -227,12 +163,12 @@ RSpec/ContextWording:
227
163
  - 'spec/fractor/supervisor_spec.rb'
228
164
  - 'spec/fractor_spec.rb'
229
165
 
230
- # Offense count: 28
166
+ # Offense count: 29
231
167
  # Configuration parameters: IgnoredMetadata.
232
168
  RSpec/DescribeClass:
233
169
  Enabled: false
234
170
 
235
- # Offense count: 542
171
+ # Offense count: 549
236
172
  # Configuration parameters: CountAsOne.
237
173
  RSpec/ExampleLength:
238
174
  Max: 47
@@ -293,7 +229,7 @@ RSpec/LeakyConstantDeclaration:
293
229
  - 'spec/fractor/worker_timeout_spec.rb'
294
230
  - 'spec/fractor/workflow/execution_strategy_spec.rb'
295
231
 
296
- # Offense count: 19
232
+ # Offense count: 24
297
233
  # Configuration parameters: EnforcedStyle.
298
234
  # SupportedStyles: have_received, receive
299
235
  RSpec/MessageSpies:
@@ -313,11 +249,11 @@ RSpec/MultipleDescribes:
313
249
  - 'spec/fractor/workflow/retry_config_spec.rb'
314
250
  - 'spec/fractor/workflow/retry_strategy_spec.rb'
315
251
 
316
- # Offense count: 635
252
+ # Offense count: 636
317
253
  RSpec/MultipleExpectations:
318
254
  Max: 12
319
255
 
320
- # Offense count: 50
256
+ # Offense count: 52
321
257
  # Configuration parameters: AllowSubject.
322
258
  RSpec/MultipleMemoizedHelpers:
323
259
  Max: 9
@@ -364,13 +300,6 @@ Security/MarshalLoad:
364
300
  Exclude:
365
301
  - 'lib/fractor/queue_persister.rb'
366
302
 
367
- # Offense count: 2
368
- # This cop supports safe autocorrection (--autocorrect).
369
- Style/MultilineIfModifier:
370
- Exclude:
371
- - 'lib/fractor/queue_persister.rb'
372
- - 'lib/fractor/result_cache.rb'
373
-
374
303
  # Offense count: 1
375
304
  # Configuration parameters: AllowedMethods.
376
305
  # AllowedMethods: respond_to_missing?
@@ -378,10 +307,18 @@ Style/OptionalBooleanParameter:
378
307
  Exclude:
379
308
  - 'lib/fractor/workflow/job.rb'
380
309
 
381
- # Offense count: 2
310
+ # Offense count: 1
311
+ # This cop supports safe autocorrection (--autocorrect).
312
+ # Configuration parameters: AllowedMethods.
313
+ # AllowedMethods: nonzero?
314
+ Style/RedundantCondition:
315
+ Exclude:
316
+ - 'lib/fractor/supervisor.rb'
317
+
318
+ # Offense count: 1
382
319
  # This cop supports safe autocorrection (--autocorrect).
383
320
  # Configuration parameters: EnforcedStyleForMultiline.
384
321
  # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
385
322
  Style/TrailingCommaInArguments:
386
323
  Exclude:
387
- - 'spec/examples/workflow/retry_workflow_spec.rb'
324
+ - 'lib/fractor/supervisor.rb'
@@ -0,0 +1,317 @@
1
+ # Fractor Architecture
2
+
3
+ This document provides architecture diagrams and descriptions of the Fractor framework's components.
4
+
5
+ ## Overview
6
+
7
+ Fractor is a function-driven Ractors framework for Ruby that provides true parallelism using Ruby's Ractor feature with automatic work distribution across isolated workers.
8
+
9
+ ## High-Level Architecture
10
+
11
+ ```mermaid
12
+ graph TB
13
+ subgraph "Application Layer"
14
+ Work[Work<br/>Immutable Input]
15
+ Worker[Worker<br/>Processing Logic]
16
+ WorkResult[WorkResult<br/>Success/Error Output]
17
+ end
18
+
19
+ subgraph "Orchestration Layer"
20
+ Supervisor[Supervisor<br/>Main Orchestrator]
21
+ ContinuousServer[ContinuousServer<br/>Long-Running Mode]
22
+ WorkflowExecutor[WorkflowExecutor<br/>Multi-Step Pipelines]
23
+ end
24
+
25
+ subgraph "Concurrency Layer"
26
+ WorkQueue[WorkQueue<br/>Thread-Safe Queue]
27
+ ResultAggregator[ResultAggregator<br/>Thread-Safe Results]
28
+ CallbackRegistry[CallbackRegistry<br/>Event Callbacks]
29
+ WrappedRactor[WrappedRactor<br/>Ractor Wrapper]
30
+ WorkDistributionManager[WorkDistributionManager<br/>Idle Worker Tracking]
31
+ end
32
+
33
+ subgraph "Ractor Layer"
34
+ Ractor1[Ractor 1]
35
+ Ractor2[Ractor 2]
36
+ Ractor3[Ractor 3]
37
+ end
38
+
39
+ Work --> Supervisor
40
+ Worker --> WorkflowExecutor
41
+ WorkResult --> ResultAggregator
42
+
43
+ Supervisor --> WorkQueue
44
+ Supervisor --> ResultAggregator
45
+ Supervisor --> CallbackRegistry
46
+ Supervisor --> WorkDistributionManager
47
+
48
+ ContinuousServer --> Supervisor
49
+
50
+ WorkflowExecutor --> Supervisor
51
+ WorkflowExecutor --> WorkQueue
52
+
53
+ WorkDistributionManager --> WrappedRactor
54
+ WrappedRactor --> Ractor1
55
+ WrappedRactor --> Ractor2
56
+ WrappedRactor --> Ractor3
57
+
58
+ Ractor1 --> Worker
59
+ Ractor2 --> Worker
60
+ Ractor3 --> Worker
61
+
62
+ style Work fill:#e1f5e1
63
+ style Worker fill:#e1f5e1
64
+ style WorkResult fill:#e1f5e1
65
+ style Supervisor fill:#e3f2fd
66
+ style ContinuousServer fill:#e3f2fd
67
+ style WorkflowExecutor fill:#e3f2fd
68
+ style WrappedRactor fill:#fff3e0
69
+ style Ractor1 fill:#fce4ec
70
+ style Ractor2 fill:#fce4ec
71
+ style Ractor3 fill:#fce4ec
72
+ ```
73
+
74
+ ## Component Relationships
75
+
76
+ ```mermaid
77
+ graph LR
78
+ subgraph "User Code"
79
+ MyWork[MyWork < Work]
80
+ MyWorker[MyWorker < Worker]
81
+ end
82
+
83
+ subgraph "Fractor Core"
84
+ Supervisor[Supervisor]
85
+ Queue[WorkQueue]
86
+ Results[ResultAggregator]
87
+ end
88
+
89
+ subgraph "Worker Pool"
90
+ W1[Worker Ractor 1]
91
+ W2[Worker Ractor 2]
92
+ W3[Worker Ractor 3]
93
+ end
94
+
95
+ MyWork --> Supervisor
96
+ MyWorker --> Supervisor
97
+
98
+ Supervisor --> Queue
99
+ Queue --> W1
100
+ Queue --> W2
101
+ Queue --> W3
102
+
103
+ W1 --> Results
104
+ W2 --> Results
105
+ W3 --> Results
106
+
107
+ Results --> Supervisor
108
+ Supervisor --> MyWork
109
+ ```
110
+
111
+ ## Pipeline Mode Execution Flow
112
+
113
+ ```mermaid
114
+ sequenceDiagram
115
+ participant User
116
+ participant Supervisor
117
+ participant WorkQueue
118
+ participant Worker as Worker Ractor
119
+ participant Results
120
+ participant Callback as CallbackRegistry
121
+
122
+ User->>Supervisor: new(worker_pools: [...])
123
+ User->>Supervisor: add_work_items(items)
124
+ Supervisor->>WorkQueue: enqueue items
125
+ User->>Supervisor: run()
126
+
127
+ loop Main Loop
128
+ Supervisor->>WorkQueue: pop_batch()
129
+ WorkQueue-->>Supervisor: work items
130
+
131
+ Supervisor->>Worker: send work
132
+ Worker->>Worker: process(work)
133
+ Worker-->>Supervisor: WorkResult
134
+ Supervisor->>Results: add(result)
135
+
136
+ Supervisor->>Callback: process_work_callbacks()
137
+ Callback-->>Supervisor: new_work (optional)
138
+ end
139
+
140
+ Supervisor-->>User: results
141
+ ```
142
+
143
+ ## Continuous Mode Execution Flow
144
+
145
+ ```mermaid
146
+ sequenceDiagram
147
+ participant User
148
+ participant Server as ContinuousServer
149
+ participant Supervisor
150
+ participant Queue as WorkQueue
151
+ participant Callbacks as CallbackRegistry
152
+
153
+ User->>Server: new(worker_pools, work_queue)
154
+ Server->>Supervisor: new(continuous_mode: true)
155
+ Queue->>Supervisor: register_work_source()
156
+ Server->>Server: run()
157
+
158
+ loop Continuous Processing
159
+ Supervisor->>Callbacks: process_work_callbacks()
160
+ Callbacks-->>Supervisor: new work items
161
+ Supervisor->>Queue: enqueue new work
162
+ Note over Supervisor,Queue: Distribute to workers
163
+
164
+ Server->>Server: on_result callback
165
+ Server->>Server: on_error callback
166
+ end
167
+
168
+ User->>Server: stop() / Ctrl+C
169
+ Server->>Supervisor: stop()
170
+ Server-->>User: shutdown complete
171
+ ```
172
+
173
+ ## Workflow System Architecture
174
+
175
+ ```mermaid
176
+ graph TB
177
+ subgraph "Workflow Definition"
178
+ DSL[Workflow DSL]
179
+ Builder[Workflow Builder]
180
+ Job[Job Definitions]
181
+ end
182
+
183
+ subgraph "Workflow Execution"
184
+ Executor[WorkflowExecutor]
185
+ Resolver[DependencyResolver<br/>Topological Sort]
186
+ Logger[WorkflowExecutionLogger]
187
+ end
188
+
189
+ subgraph "Execution Components"
190
+ JobExecutor[JobExecutor]
191
+ Retry[RetryOrchestrator]
192
+ Circuit[CircuitBreakerOrchestrator]
193
+ Fallback[FallbackJobHandler]
194
+ DLQ[DeadLetterQueue]
195
+ end
196
+
197
+ DSL --> Builder
198
+ Builder --> Job
199
+ Job --> Executor
200
+
201
+ Executor --> Resolver
202
+ Executor --> Logger
203
+ Executor --> JobExecutor
204
+
205
+ JobExecutor --> Retry
206
+ JobExecutor --> Circuit
207
+ JobExecutor --> Fallback
208
+ JobExecutor --> DLQ
209
+ ```
210
+
211
+ ## Ruby Version-Specific Architecture
212
+
213
+ ```mermaid
214
+ graph LR
215
+ subgraph "Ruby 3.x"
216
+ R3Handler[MainLoopHandler]
217
+ R3Wrapped[WrappedRactor]
218
+ R3Method[Ractor.yield / Ractor.receive]
219
+ end
220
+
221
+ subgraph "Ruby 4.0+"
222
+ R4Handler[MainLoopHandler4]
223
+ R4Wrapped[WrappedRactor4]
224
+ R4Method[Ractor::Port / Ractor.select]
225
+ end
226
+
227
+ subgraph "Shared"
228
+ Supervisor[Supervisor]
229
+ Common[Common Components]
230
+ end
231
+
232
+ Supervisor --> R3Handler
233
+ Supervisor --> R4Handler
234
+
235
+ R3Handler --> R3Wrapped
236
+ R3Wrapped --> R3Method
237
+
238
+ R4Handler --> R4Wrapped
239
+ R4Wrapped --> R4Method
240
+
241
+ R3Handler --> Common
242
+ R4Handler --> Common
243
+ ```
244
+
245
+ ## Component Responsibilities
246
+
247
+ ### Application Layer
248
+
249
+ | Component | Responsibility |
250
+ |-----------|---------------|
251
+ | **Work** | Immutable data container with input data |
252
+ | **Worker** | Processing logic with `process(work)` method |
253
+ | **WorkResult** | Contains success/failure status, result value, or error |
254
+
255
+ ### Orchestration Layer
256
+
257
+ | Component | Responsibility |
258
+ |-----------|---------------|
259
+ | **Supervisor** | Main orchestrator for pipeline mode, manages worker lifecycle |
260
+ | **ContinuousServer** | High-level wrapper for long-running services |
261
+ | **WorkflowExecutor** | Orchestrates multi-step workflow executions |
262
+
263
+ ### Concurrency Layer
264
+
265
+ | Component | Responsibility |
266
+ |-----------|---------------|
267
+ | **WorkQueue** | Thread-safe queue for work items |
268
+ | **ResultAggregator** | Thread-safe result collection with event notifications |
269
+ | **CallbackRegistry** | Manages work source and error callbacks |
270
+ | **WrappedRactor** | Safe wrapper around Ruby Ractor with version-specific implementations |
271
+ | **WorkDistributionManager** | Tracks idle workers and distributes work efficiently |
272
+
273
+ ### Ractor Layer
274
+
275
+ | Component | Responsibility |
276
+ |-----------|---------------|
277
+ | **Ractor 1, 2, 3...** | Isolated Ruby Ractors containing Worker instances |
278
+ | **Worker instances** | Each Ractor has its own Worker instance for processing |
279
+
280
+ ## Data Flow
281
+
282
+ ### Work Processing Flow
283
+
284
+ ```mermaid
285
+ graph LR
286
+ A[User creates Work] --> B[Supervisor.add_work_item]
287
+ B --> C[WorkQueue]
288
+ C --> D[WorkDistributionManager]
289
+ D --> E[Idle Worker Ractor]
290
+ E --> F[Worker.process]
291
+ F --> G[WorkResult]
292
+ G --> H[ResultAggregator]
293
+ H --> I[User retrieves results]
294
+ ```
295
+
296
+ ### Error Handling Flow
297
+
298
+ ```mermaid
299
+ graph LR
300
+ A[Worker.process raises error] --> B[WorkResult with error]
301
+ B --> C[ErrorReporter]
302
+ C --> D[ErrorStatistics]
303
+ C --> E[ErrorCallbacks]
304
+ E --> F[User error handler]
305
+ D --> G[ErrorReportGenerator]
306
+ G --> H[Formatted error output]
307
+ ```
308
+
309
+ ## Key Design Principles
310
+
311
+ 1. **Function-Driven**: Work is defined as input → processing → output
312
+ 2. **Message Passing**: Ractors communicate via messages, no shared state
313
+ 3. **Immutability**: Work objects are immutable, ensuring thread safety
314
+ 4. **Isolation**: Each Worker runs in its own Ractor with isolated memory
315
+ 5. **Scalability**: Automatically distribute work across available workers
316
+ 6. **Fault Tolerance**: Errors are captured without crashing other workers
317
+ 7. **Version Compatibility**: Separate implementations for Ruby 3.x and 4.0+