tasker-rb 0.1.1 → 0.1.2
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/README.md +2 -34
- data/ext/tasker_core/Cargo.toml +1 -1
- data/lib/tasker_core/client.rb +165 -0
- data/lib/tasker_core/registry/resolvers/class_constant_resolver.rb +1 -1
- data/lib/tasker_core/version.rb +1 -1
- data/lib/tasker_core.rb +1 -0
- metadata +2 -2
- data/lib/tasker_core/tasker_rb.so +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c505f5e0ee2615e50e4bd56c0c6e3fd7900837dcaf8454f828e197f15f9328d
|
|
4
|
+
data.tar.gz: a4fbdabbf56b6798bc0b73d16fe894d3b10e92a554a9245a361c2724f16c5a43
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c847a219fe05381929501d8789c40e2be73436910461b92219c96d4510eb6ef51eb8bf371ad8555532e3fe4f6111af5706272600c603d90fb884f0c65fba02e1
|
|
7
|
+
data.tar.gz: 213e3946bef1bc91de6f9e69614509f48061079233e71697658e8eec556fa6f12a5e940e8d509671a10b77fbf4216ec22e2d529646147ba638735b25f861b31e
|
data/README.md
CHANGED
|
@@ -2,32 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Ruby FFI bindings for the high-performance Tasker Core Rust orchestration engine.
|
|
4
4
|
|
|
5
|
-
## Status
|
|
5
|
+
## Status
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- ✅ **Monorepo Integration**: Successfully integrated into the main tasker-core repository
|
|
10
|
-
- ✅ **Cargo Workspace**: Properly configured as a workspace member
|
|
11
|
-
- ✅ **Magnus FFI Setup**: Basic Ruby module initialization working
|
|
12
|
-
- ✅ **Rust Compilation**: All Rust code compiles successfully
|
|
13
|
-
- ✅ **Build System**: CI/CD workflows configured for cross-platform testing
|
|
14
|
-
|
|
15
|
-
## Current Implementation
|
|
16
|
-
|
|
17
|
-
This is a **foundational version** that establishes the structure:
|
|
18
|
-
|
|
19
|
-
```rust
|
|
20
|
-
// Ruby module available:
|
|
21
|
-
TaskerCore::RUST_VERSION # "0.1.0"
|
|
22
|
-
TaskerCore::STATUS # "foundation"
|
|
23
|
-
TaskerCore::FEATURES # "module_init"
|
|
24
|
-
|
|
25
|
-
// Error classes defined:
|
|
26
|
-
TaskerCore::Error
|
|
27
|
-
TaskerCore::OrchestrationError
|
|
28
|
-
TaskerCore::DatabaseError
|
|
29
|
-
TaskerCore::FFIError
|
|
30
|
-
```
|
|
7
|
+
Production ready. Ruby FFI bindings provide full step handler execution via Magnus.
|
|
31
8
|
|
|
32
9
|
## Development Commands
|
|
33
10
|
|
|
@@ -45,15 +22,6 @@ rake spec
|
|
|
45
22
|
rake setup
|
|
46
23
|
```
|
|
47
24
|
|
|
48
|
-
## Next Phase: Full Implementation
|
|
49
|
-
|
|
50
|
-
The next development phase will implement:
|
|
51
|
-
|
|
52
|
-
1. **Complete WorkflowCoordinator API**
|
|
53
|
-
2. **Ruby ↔ Rust type conversions**
|
|
54
|
-
3. **Framework adapter for Rails integration**
|
|
55
|
-
4. **Performance benchmarks and validation**
|
|
56
|
-
|
|
57
25
|
## Architecture
|
|
58
26
|
|
|
59
27
|
This gem follows the **delegation-based architecture**:
|
data/ext/tasker_core/Cargo.toml
CHANGED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TaskerCore
|
|
4
|
+
# High-level client wrapper around the TaskerCore FFI client methods.
|
|
5
|
+
#
|
|
6
|
+
# The raw FFI exposes `TaskerCore::FFI.client_create_task(hash)` and similar
|
|
7
|
+
# methods that require callers to construct complete request hashes with all
|
|
8
|
+
# required fields (initiator, source_system, reason, etc.) and return plain
|
|
9
|
+
# hashes. This module provides keyword-argument methods with sensible defaults
|
|
10
|
+
# and wraps responses into typed `ClientTypes::*` Dry::Struct objects.
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a task with defaults
|
|
13
|
+
# response = TaskerCore::Client.create_task(
|
|
14
|
+
# name: 'process_order',
|
|
15
|
+
# namespace: 'ecommerce',
|
|
16
|
+
# context: { order_id: 123 }
|
|
17
|
+
# )
|
|
18
|
+
# response.task_uuid # => "550e8400-..."
|
|
19
|
+
# response.status # => "pending"
|
|
20
|
+
#
|
|
21
|
+
# @example Getting a task
|
|
22
|
+
# task = TaskerCore::Client.get_task("550e8400-...")
|
|
23
|
+
# task.name # => "process_order"
|
|
24
|
+
# task.namespace # => "ecommerce"
|
|
25
|
+
#
|
|
26
|
+
# @example Listing tasks with filters
|
|
27
|
+
# list = TaskerCore::Client.list_tasks(namespace: 'ecommerce', limit: 10)
|
|
28
|
+
# list.tasks.size # => 3
|
|
29
|
+
# list.pagination # => { "total_count" => 42, ... }
|
|
30
|
+
module Client
|
|
31
|
+
module_function
|
|
32
|
+
|
|
33
|
+
# Create a task via the orchestration API.
|
|
34
|
+
#
|
|
35
|
+
# @param name [String] Named task template name
|
|
36
|
+
# @param namespace [String] Task namespace (default: "default")
|
|
37
|
+
# @param context [Hash] Workflow context passed to step handlers
|
|
38
|
+
# @param version [String] Template version (default: "1.0.0")
|
|
39
|
+
# @param initiator [String] Who initiated the request
|
|
40
|
+
# @param source_system [String] Originating system
|
|
41
|
+
# @param reason [String] Reason for creating the task
|
|
42
|
+
# @param options [Hash] Additional TaskRequest fields
|
|
43
|
+
# @return [ClientTypes::TaskResponse, Hash] Typed response or raw hash on schema mismatch
|
|
44
|
+
def create_task(name:, namespace: 'default', context: {}, version: '1.0.0',
|
|
45
|
+
initiator: 'tasker-core-ruby', source_system: 'tasker-core',
|
|
46
|
+
reason: 'Task requested', **options)
|
|
47
|
+
request = {
|
|
48
|
+
'name' => name,
|
|
49
|
+
'namespace' => namespace,
|
|
50
|
+
'version' => version,
|
|
51
|
+
'context' => deep_to_hash(context),
|
|
52
|
+
'initiator' => initiator,
|
|
53
|
+
'source_system' => source_system,
|
|
54
|
+
'reason' => reason
|
|
55
|
+
}
|
|
56
|
+
options.each { |k, v| request[k.to_s] = v }
|
|
57
|
+
|
|
58
|
+
response = TaskerCore::FFI.client_create_task(request)
|
|
59
|
+
wrap_response(response, Types::ClientTaskResponse)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Get a task by UUID.
|
|
63
|
+
#
|
|
64
|
+
# @param task_uuid [String] The task UUID
|
|
65
|
+
# @return [ClientTypes::TaskResponse, Hash] Typed response or raw hash
|
|
66
|
+
def get_task(task_uuid)
|
|
67
|
+
response = TaskerCore::FFI.client_get_task(task_uuid.to_s)
|
|
68
|
+
wrap_response(response, Types::ClientTaskResponse)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# List tasks with optional filtering and pagination.
|
|
72
|
+
#
|
|
73
|
+
# @param limit [Integer] Maximum number of results (default: 50)
|
|
74
|
+
# @param offset [Integer] Pagination offset (default: 0)
|
|
75
|
+
# @param namespace [String, nil] Filter by namespace
|
|
76
|
+
# @param status [String, nil] Filter by status
|
|
77
|
+
# @return [ClientTypes::TaskListResponse, Hash] Typed response or raw hash
|
|
78
|
+
def list_tasks(limit: 50, offset: 0, namespace: nil, status: nil)
|
|
79
|
+
response = TaskerCore::FFI.client_list_tasks(limit, offset, namespace, status)
|
|
80
|
+
wrap_response(response, Types::ClientTaskListResponse)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Cancel a task by UUID.
|
|
84
|
+
#
|
|
85
|
+
# @param task_uuid [String] The task UUID
|
|
86
|
+
# @return [Hash] Cancellation result
|
|
87
|
+
def cancel_task(task_uuid)
|
|
88
|
+
TaskerCore::FFI.client_cancel_task(task_uuid.to_s)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# List workflow steps for a task.
|
|
92
|
+
#
|
|
93
|
+
# @param task_uuid [String] The task UUID
|
|
94
|
+
# @return [Array<ClientTypes::StepResponse>, Array<Hash>] Typed steps or raw hashes
|
|
95
|
+
def list_task_steps(task_uuid)
|
|
96
|
+
response = TaskerCore::FFI.client_list_task_steps(task_uuid.to_s)
|
|
97
|
+
return response unless response.is_a?(Array)
|
|
98
|
+
|
|
99
|
+
response.map { |step| wrap_response(step, Types::ClientStepResponse) }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Get a specific workflow step.
|
|
103
|
+
#
|
|
104
|
+
# @param task_uuid [String] The task UUID
|
|
105
|
+
# @param step_uuid [String] The step UUID
|
|
106
|
+
# @return [ClientTypes::StepResponse, Hash] Typed response or raw hash
|
|
107
|
+
def get_step(task_uuid, step_uuid)
|
|
108
|
+
response = TaskerCore::FFI.client_get_step(task_uuid.to_s, step_uuid.to_s)
|
|
109
|
+
wrap_response(response, Types::ClientStepResponse)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Get audit history for a workflow step.
|
|
113
|
+
#
|
|
114
|
+
# @param task_uuid [String] The task UUID
|
|
115
|
+
# @param step_uuid [String] The step UUID
|
|
116
|
+
# @return [Array<ClientTypes::StepAuditResponse>, Array<Hash>] Typed audit entries or raw hashes
|
|
117
|
+
def get_step_audit_history(task_uuid, step_uuid)
|
|
118
|
+
response = TaskerCore::FFI.client_get_step_audit_history(task_uuid.to_s, step_uuid.to_s)
|
|
119
|
+
return response unless response.is_a?(Array)
|
|
120
|
+
|
|
121
|
+
response.map { |entry| wrap_response(entry, Types::ClientStepAuditResponse) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Check orchestration API health.
|
|
125
|
+
#
|
|
126
|
+
# @return [ClientTypes::HealthResponse, Hash] Typed response or raw hash
|
|
127
|
+
def health_check
|
|
128
|
+
response = TaskerCore::FFI.client_health_check
|
|
129
|
+
wrap_response(response, Types::ClientHealthResponse)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @api private
|
|
133
|
+
# Wrap a raw FFI hash response into a Dry::Struct type.
|
|
134
|
+
# Falls back to the raw hash if the schema doesn't match,
|
|
135
|
+
# providing forward-compatibility when the API adds new fields.
|
|
136
|
+
def wrap_response(raw, type_class)
|
|
137
|
+
return raw unless raw.is_a?(Hash)
|
|
138
|
+
|
|
139
|
+
# Dry::Struct requires symbolized keys; raw FFI returns string keys
|
|
140
|
+
type_class.new(raw.transform_keys(&:to_sym))
|
|
141
|
+
rescue Dry::Struct::Error, KeyError, Dry::Types::ConstraintError
|
|
142
|
+
raw
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @api private
|
|
146
|
+
# Recursively convert ActionController::Parameters (and similar) to plain hashes/arrays.
|
|
147
|
+
def deep_to_hash(obj)
|
|
148
|
+
case obj
|
|
149
|
+
when Hash
|
|
150
|
+
obj.transform_values { |v| deep_to_hash(v) }
|
|
151
|
+
when Array
|
|
152
|
+
obj.map { |v| deep_to_hash(v) }
|
|
153
|
+
else
|
|
154
|
+
# Handle ActionController::Parameters if available (Rails contexts)
|
|
155
|
+
if obj.respond_to?(:to_unsafe_h)
|
|
156
|
+
obj.to_unsafe_h.transform_values { |v| deep_to_hash(v) }
|
|
157
|
+
else
|
|
158
|
+
obj
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private_class_method :wrap_response, :deep_to_hash
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -125,7 +125,7 @@ module TaskerCore
|
|
|
125
125
|
# @return [Boolean] true if responds to method
|
|
126
126
|
def responds_to_method?(klass, method_name)
|
|
127
127
|
# Check instance methods (most common case)
|
|
128
|
-
klass.
|
|
128
|
+
klass.method_defined?(method_name) ||
|
|
129
129
|
# Check if the class itself responds (for class methods)
|
|
130
130
|
klass.respond_to?(method_name)
|
|
131
131
|
end
|
data/lib/tasker_core/version.rb
CHANGED
data/lib/tasker_core.rb
CHANGED
|
@@ -138,6 +138,7 @@ require_relative 'tasker_core/internal'
|
|
|
138
138
|
require_relative 'tasker_core/template_discovery'
|
|
139
139
|
require_relative 'tasker_core/test_environment'
|
|
140
140
|
require_relative 'tasker_core/types'
|
|
141
|
+
require_relative 'tasker_core/client'
|
|
141
142
|
require_relative 'tasker_core/models'
|
|
142
143
|
require_relative 'tasker_core/handlers'
|
|
143
144
|
require_relative 'tasker_core/batch_processing/batch_worker_context'
|
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.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pete Taylor
|
|
@@ -233,6 +233,7 @@ files:
|
|
|
233
233
|
- lib/tasker_core/batch_processing/batch_aggregation_scenario.rb
|
|
234
234
|
- lib/tasker_core/batch_processing/batch_worker_context.rb
|
|
235
235
|
- lib/tasker_core/bootstrap.rb
|
|
236
|
+
- lib/tasker_core/client.rb
|
|
236
237
|
- lib/tasker_core/domain_events.rb
|
|
237
238
|
- lib/tasker_core/domain_events/base_publisher.rb
|
|
238
239
|
- lib/tasker_core/domain_events/base_subscriber.rb
|
|
@@ -268,7 +269,6 @@ files:
|
|
|
268
269
|
- lib/tasker_core/step_handler/mixins/decision.rb
|
|
269
270
|
- lib/tasker_core/subscriber.rb
|
|
270
271
|
- lib/tasker_core/task_handler/base.rb
|
|
271
|
-
- lib/tasker_core/tasker_rb.so
|
|
272
272
|
- lib/tasker_core/template_discovery.rb
|
|
273
273
|
- lib/tasker_core/tracing.rb
|
|
274
274
|
- lib/tasker_core/types.rb
|
|
Binary file
|