tasker-rb 0.1.7 → 0.1.8
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 +4 -4
- data/ext/tasker_core/Cargo.toml +4 -4
- data/lib/tasker_core/event_bridge.rb +73 -9
- data/lib/tasker_core/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: efbbc9f01809d4ac82732ea8b7d7f906f57fb939879c78f3ca448447211abd21
|
|
4
|
+
data.tar.gz: 7b7b1e5a38af3a78d5f090a725c5db85c49e4193e12440ed9a9b802972718112
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05f12f661859b22dd1446bd6c5b162523c74f5640cbeeff1e4027416c07bca1d05160fd6700405d54453b34bc0acab5bad0b4e156e89bb7e1510462593b00ff1
|
|
7
|
+
data.tar.gz: 418b0a95010e8b500630769702357c63fcbba996918b35aace2b65364b73d6126a7b34cd7282e97c82e4b802be31b30ea2dac3f92f1faa08560d2cf6e208df26
|
data/ext/tasker_core/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "tasker-rb"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.6"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
description = "Ruby bindings for tasker-core: High-performance workflow orchestration"
|
|
6
6
|
readme = "../../../../README.md"
|
|
@@ -66,8 +66,8 @@ sqlx = { version = "0.8", features = [
|
|
|
66
66
|
# Both path (for workspace builds) and version (for standalone/published builds).
|
|
67
67
|
# cargo publish strips the path field, leaving only the version for crates.io resolution.
|
|
68
68
|
# Version pins are updated by scripts/release/update-versions.sh during release-prepare.
|
|
69
|
-
tasker-shared = { path = "../../../../tasker-shared", version = "=0.1.
|
|
70
|
-
tasker-worker = { path = "../../../../tasker-worker", version = "=0.1.
|
|
69
|
+
tasker-shared = { path = "../../../../tasker-shared", version = "=0.1.6" }
|
|
70
|
+
tasker-worker = { path = "../../../../tasker-worker", version = "=0.1.6" }
|
|
71
71
|
# Error handling
|
|
72
72
|
thiserror = "2.0"
|
|
73
73
|
# Async runtime for blocking on futures in FFI
|
|
@@ -80,7 +80,7 @@ uuid = { version = "1.11", features = ["serde", "v4", "v7"] }
|
|
|
80
80
|
workspace_tools = { version = "0.11.0", features = ["full"] }
|
|
81
81
|
|
|
82
82
|
[dev-dependencies]
|
|
83
|
-
tasker-core = { package = "tasker-core", path = "../../../../", version = "=0.1.
|
|
83
|
+
tasker-core = { package = "tasker-core", path = "../../../../", version = "=0.1.6" }
|
|
84
84
|
|
|
85
85
|
[features]
|
|
86
86
|
default = []
|
|
@@ -194,21 +194,54 @@ module TaskerCore
|
|
|
194
194
|
|
|
195
195
|
# Send completion event back to Rust
|
|
196
196
|
# Called by StepExecutionSubscriber after handler execution
|
|
197
|
+
#
|
|
198
|
+
# serde_magnus requires string keys for deserialization into Rust structs.
|
|
199
|
+
# Ruby hashes built with symbol literals (e.g. { success: true }) must be
|
|
200
|
+
# deep-stringified before crossing the FFI boundary.
|
|
201
|
+
#
|
|
202
|
+
# If the FFI call still fails (e.g. unexpected nil, type mismatch), the
|
|
203
|
+
# fallback path constructs a guaranteed-safe failure result so the step is
|
|
204
|
+
# marked as permanently failed rather than silently lost.
|
|
197
205
|
def publish_step_completion(completion_data)
|
|
198
206
|
return unless active?
|
|
199
207
|
|
|
200
|
-
|
|
208
|
+
event_id_str = completion_data[:event_id].to_s
|
|
209
|
+
logger.debug "Sending step completion to Rust: #{event_id_str}"
|
|
201
210
|
|
|
202
211
|
# Validate completion data
|
|
203
212
|
validate_completion!(completion_data)
|
|
204
213
|
|
|
205
|
-
#
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
# serde_magnus expects string keys — convert symbol keys at the FFI boundary
|
|
215
|
+
stringified = completion_data.deep_stringify_keys
|
|
216
|
+
|
|
217
|
+
begin
|
|
218
|
+
TaskerCore::FFI.complete_step_event(event_id_str, stringified)
|
|
219
|
+
# Only publish monitoring event after successful primary FFI
|
|
220
|
+
publish('step.completion.sent', completion_data)
|
|
221
|
+
logger.debug 'Step completion sent to Rust'
|
|
222
|
+
rescue StandardError => e
|
|
223
|
+
logger.error "FFI serialization failed for event #{event_id_str}: #{e.message}"
|
|
224
|
+
logger.error e.backtrace&.first(5)&.join("\n")
|
|
225
|
+
|
|
226
|
+
# Submit a minimal failure result that is guaranteed to deserialize
|
|
227
|
+
fallback = build_ffi_safe_failure(completion_data, e)
|
|
228
|
+
begin
|
|
229
|
+
TaskerCore::FFI.complete_step_event(event_id_str, fallback)
|
|
230
|
+
logger.warn "FFI fallback failure submitted for event #{event_id_str}"
|
|
231
|
+
begin
|
|
232
|
+
publish('step.completion.sent', fallback)
|
|
233
|
+
rescue StandardError => pub_err
|
|
234
|
+
logger.warn "Monitoring publish failed after fallback: #{pub_err.message}"
|
|
235
|
+
end
|
|
236
|
+
rescue StandardError => fallback_error
|
|
237
|
+
logger.error "FFI fallback also failed for event #{event_id_str}: " \
|
|
238
|
+
"#{fallback_error.message} (original error: #{e.message})"
|
|
239
|
+
raise fallback_error
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
rescue ArgumentError
|
|
243
|
+
# Validation errors from validate_completion! should propagate
|
|
244
|
+
raise
|
|
212
245
|
rescue StandardError => e
|
|
213
246
|
logger.error "Failed to send step completion: #{e.message}"
|
|
214
247
|
logger.error e.backtrace.join("\n")
|
|
@@ -246,10 +279,13 @@ module TaskerCore
|
|
|
246
279
|
# Validate checkpoint data
|
|
247
280
|
validate_checkpoint_yield!(checkpoint_data)
|
|
248
281
|
|
|
282
|
+
# serde_magnus expects string keys — convert symbol keys at the FFI boundary
|
|
283
|
+
stringified = checkpoint_data.deep_stringify_keys
|
|
284
|
+
|
|
249
285
|
# Send to Rust via FFI (TAS-125)
|
|
250
286
|
success = TaskerCore::FFI.checkpoint_yield_step_event(
|
|
251
287
|
checkpoint_data[:event_id].to_s,
|
|
252
|
-
|
|
288
|
+
stringified
|
|
253
289
|
)
|
|
254
290
|
|
|
255
291
|
if success
|
|
@@ -311,6 +347,34 @@ module TaskerCore
|
|
|
311
347
|
completion_data[:completed_at] ||= Time.now.utc.iso8601
|
|
312
348
|
end
|
|
313
349
|
|
|
350
|
+
# Build a minimal StepExecutionResult-shaped hash that is guaranteed to
|
|
351
|
+
# deserialize through serde_magnus. Uses only string keys and primitive
|
|
352
|
+
# values so there is zero chance of a secondary serialization failure.
|
|
353
|
+
def build_ffi_safe_failure(original_data, error)
|
|
354
|
+
{
|
|
355
|
+
'step_uuid' => original_data[:step_uuid].to_s,
|
|
356
|
+
'task_uuid' => original_data[:task_uuid].to_s,
|
|
357
|
+
'success' => false,
|
|
358
|
+
'result' => {},
|
|
359
|
+
'status' => 'error',
|
|
360
|
+
'metadata' => {
|
|
361
|
+
'execution_time_ms' => 0,
|
|
362
|
+
'retryable' => false,
|
|
363
|
+
'completed_at' => Time.now.utc.iso8601,
|
|
364
|
+
'worker_id' => 'ruby_worker',
|
|
365
|
+
'custom' => {
|
|
366
|
+
'ffi_serialization_error' => error.message.to_s[0, 500],
|
|
367
|
+
'original_success' => original_data[:success].to_s
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
'error' => {
|
|
371
|
+
'message' => "FFI serialization failed: #{error.message}"[0, 500],
|
|
372
|
+
'error_type' => 'FFI_SERIALIZATION_ERROR',
|
|
373
|
+
'retryable' => false
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
end
|
|
377
|
+
|
|
314
378
|
# TAS-125: Validate checkpoint yield data before sending to Rust
|
|
315
379
|
def validate_checkpoint_yield!(checkpoint_data)
|
|
316
380
|
required_fields = %i[event_id step_uuid cursor items_processed]
|
data/lib/tasker_core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tasker-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pete Taylor
|
|
@@ -201,7 +201,7 @@ description: |
|
|
|
201
201
|
Ruby FFI bindings for tasker-core, providing 10-100x performance improvements
|
|
202
202
|
for workflow orchestration, dependency resolution, and state management.
|
|
203
203
|
|
|
204
|
-
This gem enables
|
|
204
|
+
This gem enables Ruby applications using the Tasker engine to leverage
|
|
205
205
|
Rust's performance for computationally intensive orchestration operations
|
|
206
206
|
while maintaining Ruby's flexibility for business logic.
|
|
207
207
|
email:
|
|
@@ -293,15 +293,14 @@ licenses:
|
|
|
293
293
|
metadata:
|
|
294
294
|
homepage_uri: https://github.com/tasker-systems/tasker-core
|
|
295
295
|
source_code_uri: https://github.com/tasker-systems/tasker-core/tree/main/workers/ruby
|
|
296
|
-
changelog_uri: https://github.com/tasker-systems/tasker-core/blob/main/
|
|
297
|
-
documentation_uri: https://
|
|
296
|
+
changelog_uri: https://github.com/tasker-systems/tasker-core/blob/main/CHANGELOG.md
|
|
297
|
+
documentation_uri: https://docs.tasker.systems
|
|
298
298
|
bug_tracker_uri: https://github.com/tasker-systems/tasker-core/issues
|
|
299
299
|
allowed_push_host: https://rubygems.org
|
|
300
300
|
rubygems_mfa_required: 'true'
|
|
301
301
|
post_install_message: "\n\U0001F980 tasker-rb successfully installed!\n\nThis gem
|
|
302
302
|
provides high-performance Rust-powered workflow orchestration.\n\nDocumentation:
|
|
303
|
-
https://
|
|
304
|
-
Rails integration, see the tasker-engine gem documentation.\n\n"
|
|
303
|
+
https://docs.tasker.systems\n\n"
|
|
305
304
|
rdoc_options: []
|
|
306
305
|
require_paths:
|
|
307
306
|
- lib
|