hatchet-sdk 0.6.0 → 0.8.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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +45 -0
- data/lib/hatchet/clients/rest/.openapi-generator/FILES +9 -0
- data/lib/hatchet/clients/rest/README.md +16 -3
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/filter_api.rb +4 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/operator_api.rb +405 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/webhook_api.rb +2 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/worker_api.rb +3 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/workflow_runs_api.rb +3 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/api_meta.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/create_tenant_invite_request.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/feature_flag_id.rb +2 -1
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/pause_workflow_request.rb +105 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/pause_workflow_request_pause.rb +343 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/pause_workflow_request_unpause.rb +262 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/tenant_invite.rb +11 -1
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/tenant_member.rb +11 -1
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/tenant_member_role.rb +2 -1
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/update_tenant_invite_request.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/update_tenant_member_request.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_create_http_operator_request.rb +346 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_event.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_http_operator.rb +372 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_http_operator_list.rb +231 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_task_summary.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_update_http_operator_request.rb +252 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/v1_workflow_run.rb +14 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/worker.rb +24 -4
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/workflow.rb +43 -1
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/workflow_pause_scheduled_cron_run_queue_behavior.rb +40 -0
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/models/workflow_update_request.rb +7 -8
- data/lib/hatchet/clients/rest/lib/hatchet-sdk-rest.rb +9 -0
- data/lib/hatchet/concurrency.rb +85 -18
- data/lib/hatchet/context.rb +5 -2
- data/lib/hatchet/contracts/v1/workflows_pb.rb +1 -1
- data/lib/hatchet/durable_context.rb +5 -12
- data/lib/hatchet/features/cel.rb +2 -2
- data/lib/hatchet/features/cron.rb +5 -5
- data/lib/hatchet/features/events.rb +7 -7
- data/lib/hatchet/features/filters.rb +7 -7
- data/lib/hatchet/features/logs.rb +2 -2
- data/lib/hatchet/features/metrics.rb +6 -6
- data/lib/hatchet/features/rate_limits.rb +2 -2
- data/lib/hatchet/features/runs.rb +4 -5
- data/lib/hatchet/features/scheduled.rb +7 -7
- data/lib/hatchet/features/tenant.rb +2 -2
- data/lib/hatchet/features/workers.rb +5 -5
- data/lib/hatchet/features/workflows.rb +6 -6
- data/lib/hatchet/version.rb +1 -1
- data/lib/hatchet/workflow.rb +58 -33
- data/lib/hatchet-sdk.rb +65 -32
- data/sig/hatchet/concurrency.rbs +12 -2
- metadata +11 -2
data/lib/hatchet/concurrency.rb
CHANGED
|
@@ -7,6 +7,35 @@ module Hatchet
|
|
|
7
7
|
CANCEL_NEWEST = :cancel_newest
|
|
8
8
|
GROUP_ROUND_ROBIN = :group_round_robin
|
|
9
9
|
QUEUE = :queue
|
|
10
|
+
CANCEL_QUEUED_EXCEPT_NEWEST = :cancel_queued_except_newest
|
|
11
|
+
CANCEL_QUEUED_EXCEPT_OLDEST = :cancel_queued_except_oldest
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Shared serialization helpers for concurrency entries
|
|
15
|
+
# @api private
|
|
16
|
+
module ConcurrencyProto
|
|
17
|
+
# Map Ruby symbol to v1 proto enum symbol
|
|
18
|
+
LIMIT_STRATEGY_MAP = {
|
|
19
|
+
cancel_in_progress: :CANCEL_IN_PROGRESS,
|
|
20
|
+
cancel_newest: :CANCEL_NEWEST,
|
|
21
|
+
group_round_robin: :GROUP_ROUND_ROBIN,
|
|
22
|
+
queue: :QUEUE_NEWEST,
|
|
23
|
+
drop_newest: :DROP_NEWEST,
|
|
24
|
+
cancel_queued_except_newest: :CANCEL_QUEUED_EXCEPT_NEWEST,
|
|
25
|
+
cancel_queued_except_oldest: :CANCEL_QUEUED_EXCEPT_OLDEST,
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
# Split the max_runs union onto the proto's static/expression field pair. A String is
|
|
29
|
+
# a CEL expression over task input; the static field then carries the default of 1,
|
|
30
|
+
# which only governs slots created before the expression existed (each new task's
|
|
31
|
+
# slot carries its own evaluated value).
|
|
32
|
+
# @param max_runs [Integer, String]
|
|
33
|
+
# @return [Array(Integer, String, nil)]
|
|
34
|
+
def self.split_max_runs(max_runs)
|
|
35
|
+
return [1, max_runs] if max_runs.is_a?(String)
|
|
36
|
+
|
|
37
|
+
[max_runs, nil]
|
|
38
|
+
end
|
|
10
39
|
end
|
|
11
40
|
|
|
12
41
|
# Defines a concurrency expression for workflow or task-level concurrency control
|
|
@@ -18,6 +47,22 @@ module Hatchet
|
|
|
18
47
|
# limit_strategy: :cancel_in_progress
|
|
19
48
|
# )
|
|
20
49
|
#
|
|
50
|
+
# @example Dynamic per-group limits via a CEL expression
|
|
51
|
+
# Hatchet::ConcurrencyExpression.new(
|
|
52
|
+
# expression: "input.tier",
|
|
53
|
+
# max_runs: "input.tier == 'premium' ? 10 : 1",
|
|
54
|
+
# limit_strategy: :group_round_robin
|
|
55
|
+
# )
|
|
56
|
+
#
|
|
57
|
+
# @example Tenant-scoped, shared across workflows
|
|
58
|
+
# Hatchet::ConcurrencyExpression.new(
|
|
59
|
+
# expression: "input.group",
|
|
60
|
+
# max_runs: 1,
|
|
61
|
+
# limit_strategy: :group_round_robin,
|
|
62
|
+
# name: "tenant-wide-limit",
|
|
63
|
+
# is_tenant_scoped: true
|
|
64
|
+
# )
|
|
65
|
+
#
|
|
21
66
|
# @example Task-level concurrency with multiple keys
|
|
22
67
|
# [
|
|
23
68
|
# Hatchet::ConcurrencyExpression.new(expression: "input.digit", max_runs: 8, limit_strategy: :group_round_robin),
|
|
@@ -27,50 +72,72 @@ module Hatchet
|
|
|
27
72
|
# @return [String] CEL expression evaluated against the workflow input
|
|
28
73
|
attr_reader :expression
|
|
29
74
|
|
|
30
|
-
# @return [Integer] Maximum concurrent runs for this key
|
|
75
|
+
# @return [Integer, String] Maximum concurrent runs for this key: a fixed number, or
|
|
76
|
+
# a CEL expression over task input computing the max runs for that task's
|
|
77
|
+
# concurrency group. With an expression, a group's effective limit is the value
|
|
78
|
+
# from its most recently created task.
|
|
31
79
|
attr_reader :max_runs
|
|
32
80
|
|
|
33
|
-
# @return [Symbol] Strategy when limit is exceeded (:cancel_in_progress, :cancel_newest, :group_round_robin, :queue)
|
|
81
|
+
# @return [Symbol] Strategy when limit is exceeded (:cancel_in_progress, :cancel_newest, :group_round_robin, :queue, :cancel_queued_except_newest, :cancel_queued_except_oldest)
|
|
34
82
|
attr_reader :limit_strategy
|
|
35
83
|
|
|
84
|
+
# @return [String, nil] Unique (per tenant) strategy name; required when tenant-scoped
|
|
85
|
+
attr_reader :name
|
|
86
|
+
|
|
87
|
+
# @return [Boolean] When true, the entry defines (or updates in place) a tenant-scoped
|
|
88
|
+
# strategy shared across workflows, keyed by name: every task declaring the same
|
|
89
|
+
# name consumes the same concurrency limit. The position in the concurrency list is
|
|
90
|
+
# the chain order, and chains sharing tenant-scoped strategies must order them
|
|
91
|
+
# consistently.
|
|
92
|
+
attr_reader :is_tenant_scoped
|
|
93
|
+
|
|
36
94
|
# @param expression [String] CEL expression evaluated against input
|
|
37
|
-
# @param max_runs [Integer] Maximum concurrent runs
|
|
95
|
+
# @param max_runs [Integer, String] Maximum concurrent runs, or a CEL expression computing them per group
|
|
38
96
|
# @param limit_strategy [Symbol] Strategy when limit is reached
|
|
39
|
-
|
|
97
|
+
# @param name [String, nil] Unique (per tenant) strategy name; required when tenant-scoped
|
|
98
|
+
# @param is_tenant_scoped [Boolean] Share this strategy across workflows, keyed by name
|
|
99
|
+
def initialize(expression:, max_runs: 1, limit_strategy: :cancel_in_progress, name: nil, is_tenant_scoped: false)
|
|
100
|
+
raise ArgumentError, "a name is required for tenant-scoped concurrency" if is_tenant_scoped && (name.nil? || name.empty?)
|
|
101
|
+
|
|
40
102
|
@expression = expression
|
|
41
103
|
@max_runs = max_runs
|
|
42
104
|
@limit_strategy = limit_strategy
|
|
105
|
+
@name = name
|
|
106
|
+
@is_tenant_scoped = is_tenant_scoped
|
|
43
107
|
end
|
|
44
108
|
|
|
109
|
+
# @deprecated kept for backwards compatibility; use {ConcurrencyProto::LIMIT_STRATEGY_MAP}
|
|
110
|
+
LIMIT_STRATEGY_MAP = ConcurrencyProto::LIMIT_STRATEGY_MAP
|
|
111
|
+
|
|
45
112
|
# Convert to a hash for API serialization
|
|
46
113
|
# @return [Hash]
|
|
47
114
|
def to_h
|
|
48
|
-
{
|
|
115
|
+
h = {
|
|
49
116
|
expression: @expression,
|
|
50
117
|
max_runs: @max_runs,
|
|
51
118
|
limit_strategy: @limit_strategy.to_s.upcase,
|
|
52
119
|
}
|
|
120
|
+
h[:name] = @name if @name
|
|
121
|
+
h[:is_tenant_scoped] = true if @is_tenant_scoped
|
|
122
|
+
h
|
|
53
123
|
end
|
|
54
124
|
|
|
55
|
-
# Map Ruby symbol to v1 proto enum symbol
|
|
56
|
-
LIMIT_STRATEGY_MAP = {
|
|
57
|
-
cancel_in_progress: :CANCEL_IN_PROGRESS,
|
|
58
|
-
cancel_newest: :CANCEL_NEWEST,
|
|
59
|
-
group_round_robin: :GROUP_ROUND_ROBIN,
|
|
60
|
-
queue: :QUEUE_NEWEST,
|
|
61
|
-
drop_newest: :DROP_NEWEST,
|
|
62
|
-
}.freeze
|
|
63
|
-
|
|
64
125
|
# Convert to a V1::Concurrency protobuf message
|
|
65
126
|
# @return [V1::Concurrency]
|
|
66
127
|
def to_proto
|
|
67
|
-
proto_strategy = LIMIT_STRATEGY_MAP[@limit_strategy] || :CANCEL_IN_PROGRESS
|
|
128
|
+
proto_strategy = ConcurrencyProto::LIMIT_STRATEGY_MAP[@limit_strategy] || :CANCEL_IN_PROGRESS
|
|
129
|
+
static_max, max_runs_expression = ConcurrencyProto.split_max_runs(@max_runs)
|
|
68
130
|
|
|
69
|
-
|
|
131
|
+
args = {
|
|
70
132
|
expression: @expression,
|
|
71
|
-
max_runs:
|
|
133
|
+
max_runs: static_max,
|
|
72
134
|
limit_strategy: proto_strategy,
|
|
73
|
-
|
|
135
|
+
}
|
|
136
|
+
args[:max_runs_expression] = max_runs_expression if max_runs_expression
|
|
137
|
+
args[:name] = @name if @name
|
|
138
|
+
args[:is_tenant_scoped] = true if @is_tenant_scoped
|
|
139
|
+
|
|
140
|
+
::V1::Concurrency.new(**args)
|
|
74
141
|
end
|
|
75
142
|
end
|
|
76
143
|
end
|
data/lib/hatchet/context.rb
CHANGED
|
@@ -218,9 +218,12 @@ module Hatchet
|
|
|
218
218
|
task_run_errors.find { |e| e.respond_to?(:task_name) && e.task_name == key }
|
|
219
219
|
end
|
|
220
220
|
|
|
221
|
-
# Access the worker context for worker-level operations
|
|
221
|
+
# Access the worker context for worker-level operations. The returned
|
|
222
|
+
# {WorkerContext} exposes +id+ (the worker id), +labels+ (the current
|
|
223
|
+
# worker labels), and +upsert_labels+ to add or update worker labels on
|
|
224
|
+
# the server at runtime.
|
|
222
225
|
#
|
|
223
|
-
# @return [WorkerContext, nil]
|
|
226
|
+
# @return [WorkerContext, nil] The worker context, if one is attached
|
|
224
227
|
def worker
|
|
225
228
|
@worker_context
|
|
226
229
|
end
|
|
@@ -9,7 +9,7 @@ require 'v1/shared/condition_pb'
|
|
|
9
9
|
require 'v1/shared/trigger_pb'
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
descriptor_data = "\n\x12v1/workflows.proto\x12\x02v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19v1/shared/condition.proto\x1a\x17v1/shared/trigger.proto\"[\n\x12\x43\x61ncelTasksRequest\x12\x14\n\x0c\x65xternal_ids\x18\x01 \x03(\t\x12$\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x0f.v1.TasksFilterH\x00\x88\x01\x01\x42\t\n\x07_filter\"[\n\x12ReplayTasksRequest\x12\x14\n\x0c\x65xternal_ids\x18\x01 \x03(\t\x12$\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x0f.v1.TasksFilterH\x00\x88\x01\x01\x42\t\n\x07_filter\"\xb7\x01\n\x0bTasksFilter\x12\x10\n\x08statuses\x18\x01 \x03(\t\x12)\n\x05since\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\x05until\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12\x14\n\x0cworkflow_ids\x18\x04 \x03(\t\x12\x1b\n\x13\x61\x64\x64itional_metadata\x18\x05 \x03(\tB\x08\n\x06_until\".\n\x13\x43\x61ncelTasksResponse\x12\x17\n\x0f\x63\x61ncelled_tasks\x18\x01 \x03(\t\"-\n\x13ReplayTasksResponse\x12\x16\n\x0ereplayed_tasks\x18\x01 \x03(\t\"\xae\x02\n\x19TriggerWorkflowRunRequest\x12\x15\n\rworkflow_name\x18\x01 \x01(\t\x12\r\n\x05input\x18\x02 \x01(\x0c\x12\x1b\n\x13\x61\x64\x64itional_metadata\x18\x03 \x01(\x0c\x12\x15\n\x08priority\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12U\n\x15\x64\x65sired_worker_labels\x18\x05 \x03(\x0b\x32\x36.v1.TriggerWorkflowRunRequest.DesiredWorkerLabelsEntry\x1aS\n\x18\x44\x65siredWorkerLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.v1.DesiredWorkerLabels:\x02\x38\x01\x42\x0b\n\t_priority\"1\n\x1aTriggerWorkflowRunResponse\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"X\n\x18\x42ranchDurableTaskRequest\x12\x18\n\x10task_external_id\x18\x01 \x01(\t\x12\x0f\n\x07node_id\x18\x02 \x01(\x03\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\"Y\n\x19\x42ranchDurableTaskResponse\x12\x18\n\x10task_external_id\x18\x01 \x01(\t\x12\x0f\n\x07node_id\x18\x02 \x01(\x03\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\"\xed\x04\n\x1c\x43reateWorkflowVersionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x16\n\x0e\x65vent_triggers\x18\x04 \x03(\t\x12\x15\n\rcron_triggers\x18\x05 \x03(\t\x12!\n\x05tasks\x18\x06 \x03(\x0b\x32\x12.v1.CreateTaskOpts\x12$\n\x0b\x63oncurrency\x18\x07 \x01(\x0b\x32\x0f.v1.Concurrency\x12\x17\n\ncron_input\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x30\n\x0fon_failure_task\x18\t \x01(\x0b\x32\x12.v1.CreateTaskOptsH\x01\x88\x01\x01\x12\'\n\x06sticky\x18\n \x01(\x0e\x32\x12.v1.StickyStrategyH\x02\x88\x01\x01\x12\x1d\n\x10\x64\x65\x66\x61ult_priority\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12(\n\x0f\x63oncurrency_arr\x18\x0c \x03(\x0b\x32\x0f.v1.Concurrency\x12*\n\x0f\x64\x65\x66\x61ult_filters\x18\r \x03(\x0b\x32\x11.v1.DefaultFilter\x12\x1e\n\x11input_json_schema\x18\x0e \x01(\x0cH\x04\x88\x01\x01\x12/\n\x0bidempotency\x18\x0f \x01(\x0b\x32\x15.v1.IdempotencyConfigH\x05\x88\x01\x01\x42\r\n\x0b_cron_inputB\x12\n\x10_on_failure_taskB\t\n\x07_stickyB\x13\n\x11_default_priorityB\x14\n\x12_input_json_schemaB\x0e\n\x0c_idempotency\"n\n\x11IdempotencyConfig\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\x0e\n\x06ttl_ms\x18\x02 \x01(\x03\x12*\n\x06method\x18\x03 \x01(\x0e\x32\x15.v1.IdempotencyMethodH\x00\x88\x01\x01\x42\t\n\x07_method\"`\n\x19IdempotencyCollisionError\x12 \n\x18\x65xisting_run_external_id\x18\x01 \x01(\t\x12!\n\x19\x63olliding_run_external_id\x18\x02 \x01(\t\"\x87\x01\n$BulkTriggerIdempotencyCollisionError\x12,\n$successful_workflow_run_external_ids\x18\x01 \x03(\t\x12\x31\n\ncollisions\x18\x02 \x03(\x0b\x32\x1d.v1.IdempotencyCollisionError\"T\n\rDefaultFilter\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\r\n\x05scope\x18\x02 \x01(\t\x12\x14\n\x07payload\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\n\n\x08_payload\"\
|
|
12
|
+
descriptor_data = "\n\x12v1/workflows.proto\x12\x02v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19v1/shared/condition.proto\x1a\x17v1/shared/trigger.proto\"[\n\x12\x43\x61ncelTasksRequest\x12\x14\n\x0c\x65xternal_ids\x18\x01 \x03(\t\x12$\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x0f.v1.TasksFilterH\x00\x88\x01\x01\x42\t\n\x07_filter\"[\n\x12ReplayTasksRequest\x12\x14\n\x0c\x65xternal_ids\x18\x01 \x03(\t\x12$\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x0f.v1.TasksFilterH\x00\x88\x01\x01\x42\t\n\x07_filter\"\xb7\x01\n\x0bTasksFilter\x12\x10\n\x08statuses\x18\x01 \x03(\t\x12)\n\x05since\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\x05until\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12\x14\n\x0cworkflow_ids\x18\x04 \x03(\t\x12\x1b\n\x13\x61\x64\x64itional_metadata\x18\x05 \x03(\tB\x08\n\x06_until\".\n\x13\x43\x61ncelTasksResponse\x12\x17\n\x0f\x63\x61ncelled_tasks\x18\x01 \x03(\t\"-\n\x13ReplayTasksResponse\x12\x16\n\x0ereplayed_tasks\x18\x01 \x03(\t\"\xae\x02\n\x19TriggerWorkflowRunRequest\x12\x15\n\rworkflow_name\x18\x01 \x01(\t\x12\r\n\x05input\x18\x02 \x01(\x0c\x12\x1b\n\x13\x61\x64\x64itional_metadata\x18\x03 \x01(\x0c\x12\x15\n\x08priority\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12U\n\x15\x64\x65sired_worker_labels\x18\x05 \x03(\x0b\x32\x36.v1.TriggerWorkflowRunRequest.DesiredWorkerLabelsEntry\x1aS\n\x18\x44\x65siredWorkerLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.v1.DesiredWorkerLabels:\x02\x38\x01\x42\x0b\n\t_priority\"1\n\x1aTriggerWorkflowRunResponse\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"X\n\x18\x42ranchDurableTaskRequest\x12\x18\n\x10task_external_id\x18\x01 \x01(\t\x12\x0f\n\x07node_id\x18\x02 \x01(\x03\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\"Y\n\x19\x42ranchDurableTaskResponse\x12\x18\n\x10task_external_id\x18\x01 \x01(\t\x12\x0f\n\x07node_id\x18\x02 \x01(\x03\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\"\xed\x04\n\x1c\x43reateWorkflowVersionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x16\n\x0e\x65vent_triggers\x18\x04 \x03(\t\x12\x15\n\rcron_triggers\x18\x05 \x03(\t\x12!\n\x05tasks\x18\x06 \x03(\x0b\x32\x12.v1.CreateTaskOpts\x12$\n\x0b\x63oncurrency\x18\x07 \x01(\x0b\x32\x0f.v1.Concurrency\x12\x17\n\ncron_input\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x30\n\x0fon_failure_task\x18\t \x01(\x0b\x32\x12.v1.CreateTaskOptsH\x01\x88\x01\x01\x12\'\n\x06sticky\x18\n \x01(\x0e\x32\x12.v1.StickyStrategyH\x02\x88\x01\x01\x12\x1d\n\x10\x64\x65\x66\x61ult_priority\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12(\n\x0f\x63oncurrency_arr\x18\x0c \x03(\x0b\x32\x0f.v1.Concurrency\x12*\n\x0f\x64\x65\x66\x61ult_filters\x18\r \x03(\x0b\x32\x11.v1.DefaultFilter\x12\x1e\n\x11input_json_schema\x18\x0e \x01(\x0cH\x04\x88\x01\x01\x12/\n\x0bidempotency\x18\x0f \x01(\x0b\x32\x15.v1.IdempotencyConfigH\x05\x88\x01\x01\x42\r\n\x0b_cron_inputB\x12\n\x10_on_failure_taskB\t\n\x07_stickyB\x13\n\x11_default_priorityB\x14\n\x12_input_json_schemaB\x0e\n\x0c_idempotency\"n\n\x11IdempotencyConfig\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\x0e\n\x06ttl_ms\x18\x02 \x01(\x03\x12*\n\x06method\x18\x03 \x01(\x0e\x32\x15.v1.IdempotencyMethodH\x00\x88\x01\x01\x42\t\n\x07_method\"`\n\x19IdempotencyCollisionError\x12 \n\x18\x65xisting_run_external_id\x18\x01 \x01(\t\x12!\n\x19\x63olliding_run_external_id\x18\x02 \x01(\t\"\x87\x01\n$BulkTriggerIdempotencyCollisionError\x12,\n$successful_workflow_run_external_ids\x18\x01 \x03(\t\x12\x31\n\ncollisions\x18\x02 \x03(\x0b\x32\x1d.v1.IdempotencyCollisionError\"T\n\rDefaultFilter\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\r\n\x05scope\x18\x02 \x01(\t\x12\x14\n\x07payload\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\n\n\x08_payload\"\x9d\x02\n\x0b\x43oncurrency\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\x15\n\x08max_runs\x18\x02 \x01(\x05H\x00\x88\x01\x01\x12\x39\n\x0elimit_strategy\x18\x03 \x01(\x0e\x32\x1c.v1.ConcurrencyLimitStrategyH\x01\x88\x01\x01\x12\x11\n\x04name\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10is_tenant_scoped\x18\x05 \x01(\x08H\x03\x88\x01\x01\x12 \n\x13max_runs_expression\x18\x06 \x01(\tH\x04\x88\x01\x01\x42\x0b\n\t_max_runsB\x11\n\x0f_limit_strategyB\x07\n\x05_nameB\x13\n\x11_is_tenant_scopedB\x16\n\x14_max_runs_expression\"\x89\x02\n\x0fTaskBatchConfig\x12\x16\n\x0e\x62\x61tch_max_size\x18\x01 \x01(\x05\x12\"\n\x15\x62\x61tch_max_interval_ms\x18\x02 \x01(\x05H\x00\x88\x01\x01\x12\x1c\n\x0f\x62\x61tch_group_key\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x62\x61tch_group_max_runs\x18\x04 \x01(\x05H\x02\x88\x01\x01\x12\x1d\n\x10\x62roadcast_output\x18\x05 \x01(\x08H\x03\x88\x01\x01\x42\x18\n\x16_batch_max_interval_msB\x12\n\x10_batch_group_keyB\x17\n\x15_batch_group_max_runsB\x13\n\x11_broadcast_output\"\xea\x05\n\x0e\x43reateTaskOpts\x12\x13\n\x0breadable_id\x18\x01 \x01(\t\x12\x0e\n\x06\x61\x63tion\x18\x02 \x01(\t\x12\x0f\n\x07timeout\x18\x03 \x01(\t\x12\x0e\n\x06inputs\x18\x04 \x01(\t\x12\x0f\n\x07parents\x18\x05 \x03(\t\x12\x0f\n\x07retries\x18\x06 \x01(\x05\x12,\n\x0brate_limits\x18\x07 \x03(\x0b\x32\x17.v1.CreateTaskRateLimit\x12;\n\rworker_labels\x18\x08 \x03(\x0b\x32$.v1.CreateTaskOpts.WorkerLabelsEntry\x12\x1b\n\x0e\x62\x61\x63koff_factor\x18\t \x01(\x02H\x00\x88\x01\x01\x12 \n\x13\x62\x61\x63koff_max_seconds\x18\n \x01(\x05H\x01\x88\x01\x01\x12$\n\x0b\x63oncurrency\x18\x0b \x03(\x0b\x32\x0f.v1.Concurrency\x12+\n\nconditions\x18\x0c \x01(\x0b\x32\x12.v1.TaskConditionsH\x02\x88\x01\x01\x12\x1d\n\x10schedule_timeout\x18\r \x01(\tH\x03\x88\x01\x01\x12\x12\n\nis_durable\x18\x0e \x01(\x08\x12;\n\rslot_requests\x18\x0f \x03(\x0b\x32$.v1.CreateTaskOpts.SlotRequestsEntry\x12\'\n\x05\x62\x61tch\x18\x10 \x01(\x0b\x32\x13.v1.TaskBatchConfigH\x04\x88\x01\x01\x1aL\n\x11WorkerLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.v1.DesiredWorkerLabels:\x02\x38\x01\x1a\x33\n\x11SlotRequestsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x42\x11\n\x0f_backoff_factorB\x16\n\x14_backoff_max_secondsB\r\n\x0b_conditionsB\x13\n\x11_schedule_timeoutB\x08\n\x06_batch\"\xfd\x01\n\x13\x43reateTaskRateLimit\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x12\n\x05units\x18\x02 \x01(\x05H\x00\x88\x01\x01\x12\x15\n\x08key_expr\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\nunits_expr\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1e\n\x11limit_values_expr\x18\x05 \x01(\tH\x03\x88\x01\x01\x12,\n\x08\x64uration\x18\x06 \x01(\x0e\x32\x15.v1.RateLimitDurationH\x04\x88\x01\x01\x42\x08\n\x06_unitsB\x0b\n\t_key_exprB\r\n\x0b_units_exprB\x14\n\x12_limit_values_exprB\x0b\n\t_duration\"@\n\x1d\x43reateWorkflowVersionResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\"+\n\x14GetRunDetailsRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"\xaa\x01\n\rTaskRunDetail\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\x12\x1d\n\x06status\x18\x02 \x01(\x0e\x32\r.v1.RunStatus\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06output\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x0breadable_id\x18\x05 \x01(\t\x12\x12\n\nis_evicted\x18\x06 \x01(\x08\x42\x08\n\x06_errorB\t\n\x07_output\"\x84\x02\n\x15GetRunDetailsResponse\x12\r\n\x05input\x18\x01 \x01(\x0c\x12\x1d\n\x06status\x18\x02 \x01(\x0e\x32\r.v1.RunStatus\x12:\n\ttask_runs\x18\x03 \x03(\x0b\x32\'.v1.GetRunDetailsResponse.TaskRunsEntry\x12\x0c\n\x04\x64one\x18\x04 \x01(\x08\x12\x1b\n\x13\x61\x64\x64itional_metadata\x18\x05 \x01(\x0c\x12\x12\n\nis_evicted\x18\x06 \x01(\x08\x1a\x42\n\rTaskRunsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.v1.TaskRunDetail:\x02\x38\x01*$\n\x0eStickyStrategy\x12\x08\n\x04SOFT\x10\x00\x12\x08\n\x04HARD\x10\x01*]\n\x11RateLimitDuration\x12\n\n\x06SECOND\x10\x00\x12\n\n\x06MINUTE\x10\x01\x12\x08\n\x04HOUR\x10\x02\x12\x07\n\x03\x44\x41Y\x10\x03\x12\x08\n\x04WEEK\x10\x04\x12\t\n\x05MONTH\x10\x05\x12\x08\n\x04YEAR\x10\x06*[\n\tRunStatus\x12\n\n\x06QUEUED\x10\x00\x12\x0b\n\x07RUNNING\x10\x01\x12\r\n\tCOMPLETED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\x12\r\n\tCANCELLED\x10\x04\x12\x0b\n\x07\x45VICTED\x10\x05*(\n\x11IdempotencyMethod\x12\x07\n\x03TTL\x10\x00\x12\n\n\x06STATUS\x10\x01*\xc1\x01\n\x18\x43oncurrencyLimitStrategy\x12\x16\n\x12\x43\x41NCEL_IN_PROGRESS\x10\x00\x12\x0f\n\x0b\x44ROP_NEWEST\x10\x01\x12\x10\n\x0cQUEUE_NEWEST\x10\x02\x12\x15\n\x11GROUP_ROUND_ROBIN\x10\x03\x12\x11\n\rCANCEL_NEWEST\x10\x04\x12\x1f\n\x1b\x43\x41NCEL_QUEUED_EXCEPT_NEWEST\x10\x05\x12\x1f\n\x1b\x43\x41NCEL_QUEUED_EXCEPT_OLDEST\x10\x06\x32\xcf\x03\n\x0c\x41\x64minService\x12R\n\x0bPutWorkflow\x12 .v1.CreateWorkflowVersionRequest\x1a!.v1.CreateWorkflowVersionResponse\x12>\n\x0b\x43\x61ncelTasks\x12\x16.v1.CancelTasksRequest\x1a\x17.v1.CancelTasksResponse\x12>\n\x0bReplayTasks\x12\x16.v1.ReplayTasksRequest\x1a\x17.v1.ReplayTasksResponse\x12S\n\x12TriggerWorkflowRun\x12\x1d.v1.TriggerWorkflowRunRequest\x1a\x1e.v1.TriggerWorkflowRunResponse\x12\x44\n\rGetRunDetails\x12\x18.v1.GetRunDetailsRequest\x1a\x19.v1.GetRunDetailsResponse\x12P\n\x11\x42ranchDurableTask\x12\x1c.v1.BranchDurableTaskRequest\x1a\x1d.v1.BranchDurableTaskResponseBBZ@github.com/hatchet-dev/hatchet/internal/services/shared/proto/v1b\x06proto3"
|
|
13
13
|
|
|
14
14
|
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
15
15
|
pool.add_serialized_file(descriptor_data)
|
|
@@ -5,14 +5,12 @@ require "securerandom"
|
|
|
5
5
|
|
|
6
6
|
module Hatchet
|
|
7
7
|
# Extended context for durable tasks that supports sleep and event-waiting
|
|
8
|
-
# across task suspensions.
|
|
8
|
+
# across task suspensions. All methods and attributes of {Context} are also
|
|
9
|
+
# available.
|
|
9
10
|
#
|
|
10
11
|
# Durable tasks can be suspended and resumed by the Hatchet engine,
|
|
11
12
|
# allowing long-running workflows that survive process restarts.
|
|
12
13
|
#
|
|
13
|
-
# Uses V1::V1Dispatcher for registering and listening for durable events
|
|
14
|
-
# via bidirectional gRPC streaming.
|
|
15
|
-
#
|
|
16
14
|
# @example Sleep for a duration
|
|
17
15
|
# hatchet.durable_task(name: "my_task") do |input, ctx|
|
|
18
16
|
# ctx.sleep_for(duration: 60) # sleep for 60 seconds
|
|
@@ -42,10 +40,8 @@ module Hatchet
|
|
|
42
40
|
attr_accessor :engine_version
|
|
43
41
|
|
|
44
42
|
# Sleep for a specified duration. The task is suspended and resumed
|
|
45
|
-
# by the engine after the duration expires
|
|
46
|
-
#
|
|
47
|
-
# Delegates to {#wait_for} with a {Hatchet::SleepCondition} so that both
|
|
48
|
-
# sleeps and event waits share a single registration / eviction path.
|
|
43
|
+
# by the engine after the duration expires, so no worker slot is blocked
|
|
44
|
+
# while sleeping (subject to the task's eviction policy).
|
|
49
45
|
#
|
|
50
46
|
# @param duration [Integer, String] Duration in seconds, or a duration string (e.g. "60s")
|
|
51
47
|
# @param label [String, nil] Optional wait label shown in durable event logs.
|
|
@@ -62,11 +58,8 @@ module Hatchet
|
|
|
62
58
|
# Wait for a condition to be met (event or sleep).
|
|
63
59
|
# The task is suspended and resumed when the condition is satisfied.
|
|
64
60
|
#
|
|
65
|
-
# Register the durable wait with ``send_event`` first, then start eviction
|
|
66
|
-
# tracking only while blocked on ``wait_for_callback``.
|
|
67
|
-
#
|
|
68
61
|
# @param key [String] A unique key for this wait operation
|
|
69
|
-
# @param condition [
|
|
62
|
+
# @param condition [UserEventCondition, SleepCondition, OrCondition] The condition to wait for
|
|
70
63
|
# @param label [String, nil] Optional wait label shown in durable event logs.
|
|
71
64
|
# @return [Hash] Result from the wait, including which condition was satisfied
|
|
72
65
|
def wait_for(key, condition, label: nil)
|
data/lib/hatchet/features/cel.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Hatchet
|
|
|
23
23
|
# CEL (Common Expression Language) expressions used in filters and conditions.
|
|
24
24
|
#
|
|
25
25
|
# @example Debugging a CEL expression
|
|
26
|
-
# result =
|
|
26
|
+
# result = hatchet.cel.debug(
|
|
27
27
|
# expression: 'input.value > 10',
|
|
28
28
|
# input: { value: 15 }
|
|
29
29
|
# )
|
|
@@ -59,7 +59,7 @@ module Hatchet
|
|
|
59
59
|
# @raise [RuntimeError] If no response is received from the CEL debug API
|
|
60
60
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
61
61
|
# @example
|
|
62
|
-
# result =
|
|
62
|
+
# result = hatchet.cel.debug(
|
|
63
63
|
# expression: 'input.count > 5 && metadata.env == "prod"',
|
|
64
64
|
# input: { count: 10 },
|
|
65
65
|
# additional_metadata: { env: 'prod' }
|
|
@@ -8,7 +8,7 @@ module Hatchet
|
|
|
8
8
|
# listing, and retrieving cron workflow triggers.
|
|
9
9
|
#
|
|
10
10
|
# @example Creating a cron trigger
|
|
11
|
-
# cron =
|
|
11
|
+
# cron = hatchet.cron.create(
|
|
12
12
|
# workflow_name: "my-workflow",
|
|
13
13
|
# cron_name: "daily-run",
|
|
14
14
|
# expression: "0 0 * * *",
|
|
@@ -45,7 +45,7 @@ module Hatchet
|
|
|
45
45
|
# @raise [ArgumentError] If the cron expression is invalid
|
|
46
46
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
47
47
|
# @example
|
|
48
|
-
# cron =
|
|
48
|
+
# cron = hatchet.cron.create(
|
|
49
49
|
# workflow_name: "my-workflow",
|
|
50
50
|
# cron_name: "hourly-run",
|
|
51
51
|
# expression: "0 * * * *",
|
|
@@ -76,7 +76,7 @@ module Hatchet
|
|
|
76
76
|
# @return [void]
|
|
77
77
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
78
78
|
# @example
|
|
79
|
-
#
|
|
79
|
+
# hatchet.cron.delete("cron-123")
|
|
80
80
|
def delete(cron_id)
|
|
81
81
|
@workflow_api.workflow_cron_delete(@config.tenant_id, cron_id.to_s)
|
|
82
82
|
end
|
|
@@ -94,7 +94,7 @@ module Hatchet
|
|
|
94
94
|
# @return [Object] A list of cron workflows
|
|
95
95
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
96
96
|
# @example
|
|
97
|
-
# crons =
|
|
97
|
+
# crons = hatchet.cron.list(limit: 10, workflow_name: "my-workflow")
|
|
98
98
|
def list(offset: nil, limit: nil, workflow_id: nil, additional_metadata: nil,
|
|
99
99
|
order_by_field: nil, order_by_direction: nil, workflow_name: nil, cron_name: nil)
|
|
100
100
|
@workflow_api.cron_workflow_list(
|
|
@@ -118,7 +118,7 @@ module Hatchet
|
|
|
118
118
|
# @return [Object] The requested cron workflow instance
|
|
119
119
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
120
120
|
# @example
|
|
121
|
-
# cron =
|
|
121
|
+
# cron = hatchet.cron.get("cron-123")
|
|
122
122
|
def get(cron_id)
|
|
123
123
|
@workflow_api.workflow_cron_get(@config.tenant_id, cron_id.to_s)
|
|
124
124
|
end
|
|
@@ -11,9 +11,9 @@ module Hatchet
|
|
|
11
11
|
# the REST API for read operations (list, get, etc.).
|
|
12
12
|
#
|
|
13
13
|
# @example Creating an event
|
|
14
|
-
# response = events.push(
|
|
15
|
-
#
|
|
16
|
-
#
|
|
14
|
+
# response = hatchet.events.push(
|
|
15
|
+
# "user-login",
|
|
16
|
+
# { user_id: 123, action: "login" },
|
|
17
17
|
# additional_metadata: { ip_address: "192.168.1.1" }
|
|
18
18
|
# )
|
|
19
19
|
#
|
|
@@ -53,7 +53,7 @@ module Hatchet
|
|
|
53
53
|
# @raise [ArgumentError] If required parameters are missing
|
|
54
54
|
# @raise [Hatchet::Error] If the API request fails or returns an error
|
|
55
55
|
# @example Creating a simple event
|
|
56
|
-
# response = events.create(
|
|
56
|
+
# response = hatchet.events.create(
|
|
57
57
|
# key: "user-login",
|
|
58
58
|
# data: { user_id: 123, action: "login" },
|
|
59
59
|
# additional_metadata: { ip_address: "192.168.1.1" }
|
|
@@ -80,7 +80,7 @@ module Hatchet
|
|
|
80
80
|
# @return [Object] The gRPC response containing the created event details
|
|
81
81
|
# @raise [Hatchet::Error] If the API request fails or returns an error
|
|
82
82
|
# @example Push a simple event
|
|
83
|
-
# response = events.push(
|
|
83
|
+
# response = hatchet.events.push(
|
|
84
84
|
# "user-signup",
|
|
85
85
|
# { user_id: 456, email: "user@example.com" },
|
|
86
86
|
# additional_metadata: { source: "web" }
|
|
@@ -106,7 +106,7 @@ module Hatchet
|
|
|
106
106
|
# { key: "user-signup", data: { user_id: 1 } },
|
|
107
107
|
# { key: "user-login", data: { user_id: 1 }, priority: 1 }
|
|
108
108
|
# ]
|
|
109
|
-
# response = events.bulk_push(events_data)
|
|
109
|
+
# response = hatchet.events.bulk_push(events_data)
|
|
110
110
|
def bulk_push(events, namespace: nil)
|
|
111
111
|
grpc_events = events.map do |event|
|
|
112
112
|
{
|
|
@@ -135,7 +135,7 @@ module Hatchet
|
|
|
135
135
|
# @return [HatchetSdkRest::V1EventList] List of events matching the filters
|
|
136
136
|
# @raise [Hatchet::Error] If the API request fails or returns an error
|
|
137
137
|
# @example List recent events
|
|
138
|
-
# events =
|
|
138
|
+
# events = hatchet.events.list(
|
|
139
139
|
# limit: 10,
|
|
140
140
|
# since: Time.now - 24 * 60 * 60,
|
|
141
141
|
# keys: ["user-signup", "user-login"]
|
|
@@ -8,10 +8,10 @@ module Hatchet
|
|
|
8
8
|
# listing, updating, and deleting filters in the Hatchet system.
|
|
9
9
|
#
|
|
10
10
|
# @example Listing filters
|
|
11
|
-
# filters =
|
|
11
|
+
# filters = hatchet.filters.list(limit: 10, workflow_ids: ["wf-1"])
|
|
12
12
|
#
|
|
13
13
|
# @example Creating a filter
|
|
14
|
-
# filter =
|
|
14
|
+
# filter = hatchet.filters.create(
|
|
15
15
|
# workflow_id: "wf-1",
|
|
16
16
|
# expression: 'input.priority > 5',
|
|
17
17
|
# scope: "high-priority"
|
|
@@ -40,7 +40,7 @@ module Hatchet
|
|
|
40
40
|
# @return [Object] A list of filters matching the specified criteria
|
|
41
41
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
42
42
|
# @example
|
|
43
|
-
# filters =
|
|
43
|
+
# filters = hatchet.filters.list(limit: 10, workflow_ids: ["wf-1"])
|
|
44
44
|
def list(limit: nil, offset: nil, workflow_ids: nil, scopes: nil)
|
|
45
45
|
@filter_api.v1_filter_list(
|
|
46
46
|
@config.tenant_id,
|
|
@@ -59,7 +59,7 @@ module Hatchet
|
|
|
59
59
|
# @return [Object] The filter details
|
|
60
60
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
61
61
|
# @example
|
|
62
|
-
# filter =
|
|
62
|
+
# filter = hatchet.filters.get("filter-123")
|
|
63
63
|
def get(filter_id)
|
|
64
64
|
@filter_api.v1_filter_get(@config.tenant_id, filter_id)
|
|
65
65
|
end
|
|
@@ -73,7 +73,7 @@ module Hatchet
|
|
|
73
73
|
# @return [Object] The created filter
|
|
74
74
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
75
75
|
# @example
|
|
76
|
-
# filter =
|
|
76
|
+
# filter = hatchet.filters.create(
|
|
77
77
|
# workflow_id: "wf-1",
|
|
78
78
|
# expression: 'input.value > 10',
|
|
79
79
|
# scope: "my-scope",
|
|
@@ -95,7 +95,7 @@ module Hatchet
|
|
|
95
95
|
# @return [Object] The deleted filter
|
|
96
96
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
97
97
|
# @example
|
|
98
|
-
#
|
|
98
|
+
# hatchet.filters.delete("filter-123")
|
|
99
99
|
def delete(filter_id)
|
|
100
100
|
@filter_api.v1_filter_delete(@config.tenant_id, filter_id)
|
|
101
101
|
end
|
|
@@ -107,7 +107,7 @@ module Hatchet
|
|
|
107
107
|
# @return [Object] The updated filter
|
|
108
108
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
109
109
|
# @example
|
|
110
|
-
#
|
|
110
|
+
# hatchet.filters.update("filter-123", { expression: 'input.value > 20' })
|
|
111
111
|
def update(filter_id, updates)
|
|
112
112
|
update_request = HatchetSdkRest::V1UpdateFilterRequest.new(updates)
|
|
113
113
|
@filter_api.v1_filter_update(@config.tenant_id, filter_id, update_request)
|
|
@@ -10,7 +10,7 @@ module Hatchet
|
|
|
10
10
|
# associated with task runs in the Hatchet system.
|
|
11
11
|
#
|
|
12
12
|
# @example Listing logs for a task run
|
|
13
|
-
# logs =
|
|
13
|
+
# logs = hatchet.logs.list("task-run-id", limit: 100)
|
|
14
14
|
#
|
|
15
15
|
# @since 0.1.0
|
|
16
16
|
class Logs
|
|
@@ -35,7 +35,7 @@ module Hatchet
|
|
|
35
35
|
# @return [Object] A list of log lines for the specified task run
|
|
36
36
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
37
37
|
# @example
|
|
38
|
-
# logs =
|
|
38
|
+
# logs = hatchet.logs.list("task-run-123", limit: 500, since: Time.now - 3600)
|
|
39
39
|
def list(task_run_id, limit: 1000, since: nil, until_time: nil)
|
|
40
40
|
@log_api.v1_log_line_list(
|
|
41
41
|
task_run_id,
|
|
@@ -13,10 +13,10 @@ module Hatchet
|
|
|
13
13
|
# Prometheus metrics, task statistics, and task metrics from the Hatchet system.
|
|
14
14
|
#
|
|
15
15
|
# @example Getting queue metrics
|
|
16
|
-
# metrics =
|
|
16
|
+
# metrics = hatchet.metrics.get_queue_metrics
|
|
17
17
|
#
|
|
18
18
|
# @example Getting task metrics
|
|
19
|
-
# task_metrics =
|
|
19
|
+
# task_metrics = hatchet.metrics.get_task_metrics(
|
|
20
20
|
# since: Time.now - 86400,
|
|
21
21
|
# workflow_ids: ["wf-1"]
|
|
22
22
|
# )
|
|
@@ -41,7 +41,7 @@ module Hatchet
|
|
|
41
41
|
# @return [Hash] The current queue metrics
|
|
42
42
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
43
43
|
# @example
|
|
44
|
-
# queues =
|
|
44
|
+
# queues = hatchet.metrics.get_queue_metrics
|
|
45
45
|
def get_queue_metrics
|
|
46
46
|
result = @tenant_api.tenant_get_step_run_queue_metrics(@config.tenant_id)
|
|
47
47
|
result.queues || {}
|
|
@@ -52,7 +52,7 @@ module Hatchet
|
|
|
52
52
|
# @return [String] The metrics in Prometheus text format
|
|
53
53
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
54
54
|
# @example
|
|
55
|
-
# prometheus_text =
|
|
55
|
+
# prometheus_text = hatchet.metrics.scrape_tenant_prometheus_metrics
|
|
56
56
|
def scrape_tenant_prometheus_metrics
|
|
57
57
|
@tenant_api.tenant_get_prometheus_metrics(@config.tenant_id)
|
|
58
58
|
end
|
|
@@ -62,7 +62,7 @@ module Hatchet
|
|
|
62
62
|
# @return [Object] The task statistics
|
|
63
63
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
64
64
|
# @example
|
|
65
|
-
# stats =
|
|
65
|
+
# stats = hatchet.metrics.get_task_stats
|
|
66
66
|
def get_task_stats
|
|
67
67
|
@tenant_api.tenant_get_task_stats(@config.tenant_id)
|
|
68
68
|
end
|
|
@@ -77,7 +77,7 @@ module Hatchet
|
|
|
77
77
|
# @return [TaskMetrics] Task metrics with counts per status
|
|
78
78
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
79
79
|
# @example
|
|
80
|
-
# metrics =
|
|
80
|
+
# metrics = hatchet.metrics.get_task_metrics(
|
|
81
81
|
# since: Time.now - 86400,
|
|
82
82
|
# workflow_ids: ["wf-1"]
|
|
83
83
|
# )
|
|
@@ -8,7 +8,7 @@ module Hatchet
|
|
|
8
8
|
# rate limits using the gRPC Admin client.
|
|
9
9
|
#
|
|
10
10
|
# @example Setting a rate limit
|
|
11
|
-
#
|
|
11
|
+
# hatchet.rate_limits.put(key: "api-calls", limit: 100, duration: :SECOND)
|
|
12
12
|
#
|
|
13
13
|
# @since 0.1.0
|
|
14
14
|
class RateLimits
|
|
@@ -31,7 +31,7 @@ module Hatchet
|
|
|
31
31
|
# @return [void]
|
|
32
32
|
# @raise [GRPC::BadStatus] If the gRPC request fails
|
|
33
33
|
# @example
|
|
34
|
-
#
|
|
34
|
+
# hatchet.rate_limits.put(key: "api-calls", limit: 100, duration: :SECOND)
|
|
35
35
|
def put(key:, limit:, duration: :SECOND)
|
|
36
36
|
@admin_grpc.put_rate_limit(key: key, limit: limit, duration: duration)
|
|
37
37
|
end
|
|
@@ -72,8 +72,7 @@ module Hatchet
|
|
|
72
72
|
# convenient Ruby interface.
|
|
73
73
|
#
|
|
74
74
|
# @example Creating a workflow run
|
|
75
|
-
#
|
|
76
|
-
# response = runs.create(
|
|
75
|
+
# response = hatchet.runs.create(
|
|
77
76
|
# name: "my-workflow",
|
|
78
77
|
# input: { key: "value" },
|
|
79
78
|
# additional_metadata: { source: "api" }
|
|
@@ -289,7 +288,7 @@ module Hatchet
|
|
|
289
288
|
# @raise [ArgumentError] If the workflow_name or input parameters are nil or invalid
|
|
290
289
|
# @raise [Hatchet::Error] If the API request fails or returns an error
|
|
291
290
|
# @example Creating a workflow run
|
|
292
|
-
# response = runs.create(
|
|
291
|
+
# response = hatchet.runs.create(
|
|
293
292
|
# name: "simple-workflow",
|
|
294
293
|
# input: { user_id: 123, action: "process_data" },
|
|
295
294
|
# additional_metadata: { source: "api", priority: "high" }
|
|
@@ -446,9 +445,9 @@ module Hatchet
|
|
|
446
445
|
# @raise [Timeout::Error] If the timeout is reached before completion
|
|
447
446
|
# @raise [Hatchet::Error] If the API request fails or returns an error
|
|
448
447
|
# @example Poll with default settings (1s interval, no timeout)
|
|
449
|
-
# result = runs.poll("workflow-run-123")
|
|
448
|
+
# result = hatchet.runs.poll("workflow-run-123")
|
|
450
449
|
# @example Poll with custom interval and timeout
|
|
451
|
-
# result = runs.poll("workflow-run-123", interval: 2.0, timeout: 30.0)
|
|
450
|
+
# result = hatchet.runs.poll("workflow-run-123", interval: 2.0, timeout: 30.0)
|
|
452
451
|
# @since 0.1.0
|
|
453
452
|
def poll(workflow_run_id, interval: 1.0, timeout: nil)
|
|
454
453
|
start_time = Time.now
|
|
@@ -10,7 +10,7 @@ module Hatchet
|
|
|
10
10
|
# updating, bulk operations, listing, and retrieving scheduled workflow runs.
|
|
11
11
|
#
|
|
12
12
|
# @example Creating a scheduled workflow
|
|
13
|
-
# scheduled =
|
|
13
|
+
# scheduled = hatchet.scheduled.create(
|
|
14
14
|
# workflow_name: "my-workflow",
|
|
15
15
|
# trigger_at: Time.now + 3600,
|
|
16
16
|
# input: { key: "value" },
|
|
@@ -44,7 +44,7 @@ module Hatchet
|
|
|
44
44
|
# @return [Object] The created scheduled workflow instance
|
|
45
45
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
46
46
|
# @example
|
|
47
|
-
# scheduled =
|
|
47
|
+
# scheduled = hatchet.scheduled.create(
|
|
48
48
|
# workflow_name: "my-workflow",
|
|
49
49
|
# trigger_at: Time.now + 3600,
|
|
50
50
|
# input: { key: "value" },
|
|
@@ -70,7 +70,7 @@ module Hatchet
|
|
|
70
70
|
# @return [void]
|
|
71
71
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
72
72
|
# @example
|
|
73
|
-
#
|
|
73
|
+
# hatchet.scheduled.delete("scheduled-123")
|
|
74
74
|
def delete(scheduled_id)
|
|
75
75
|
@workflow_api.workflow_scheduled_delete(@config.tenant_id, scheduled_id)
|
|
76
76
|
end
|
|
@@ -85,7 +85,7 @@ module Hatchet
|
|
|
85
85
|
# @return [Object] The updated scheduled workflow instance
|
|
86
86
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
87
87
|
# @example
|
|
88
|
-
#
|
|
88
|
+
# hatchet.scheduled.update("scheduled-123", trigger_at: Time.now + 7200)
|
|
89
89
|
def update(scheduled_id, trigger_at:)
|
|
90
90
|
request = HatchetSdkRest::UpdateScheduledWorkflowRunRequest.new(
|
|
91
91
|
trigger_at: trigger_at.utc.iso8601,
|
|
@@ -139,7 +139,7 @@ module Hatchet
|
|
|
139
139
|
# @return [Object] The bulk update response containing updated IDs and per-item errors
|
|
140
140
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
141
141
|
# @example
|
|
142
|
-
#
|
|
142
|
+
# hatchet.scheduled.bulk_update([
|
|
143
143
|
# { id: "scheduled-1", trigger_at: Time.now + 3600 },
|
|
144
144
|
# { id: "scheduled-2", trigger_at: Time.now + 7200 }
|
|
145
145
|
# ])
|
|
@@ -171,7 +171,7 @@ module Hatchet
|
|
|
171
171
|
# @return [Object] A list of scheduled workflows matching the provided filters
|
|
172
172
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
173
173
|
# @example
|
|
174
|
-
# scheduled =
|
|
174
|
+
# scheduled = hatchet.scheduled.list(limit: 10, workflow_id: "wf-1")
|
|
175
175
|
def list(offset: nil, limit: nil, workflow_id: nil, parent_workflow_run_id: nil,
|
|
176
176
|
statuses: nil, additional_metadata: nil, order_by_field: nil, order_by_direction: nil)
|
|
177
177
|
@workflow_api.workflow_scheduled_list(
|
|
@@ -195,7 +195,7 @@ module Hatchet
|
|
|
195
195
|
# @return [Object] The requested scheduled workflow instance
|
|
196
196
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
197
197
|
# @example
|
|
198
|
-
# scheduled =
|
|
198
|
+
# scheduled = hatchet.scheduled.get("scheduled-123")
|
|
199
199
|
def get(scheduled_id)
|
|
200
200
|
@workflow_api.workflow_scheduled_get(@config.tenant_id, scheduled_id)
|
|
201
201
|
end
|
|
@@ -8,7 +8,7 @@ module Hatchet
|
|
|
8
8
|
# from the Hatchet system.
|
|
9
9
|
#
|
|
10
10
|
# @example Getting the current tenant
|
|
11
|
-
# tenant_info =
|
|
11
|
+
# tenant_info = hatchet.tenant.get
|
|
12
12
|
#
|
|
13
13
|
# @since 0.1.0
|
|
14
14
|
class Tenant
|
|
@@ -29,7 +29,7 @@ module Hatchet
|
|
|
29
29
|
# @return [Object] The tenant details
|
|
30
30
|
# @raise [HatchetSdkRest::ApiError] If the API request fails
|
|
31
31
|
# @example
|
|
32
|
-
# tenant =
|
|
32
|
+
# tenant = hatchet.tenant.get
|
|
33
33
|
def get
|
|
34
34
|
@tenant_api.tenant_get(@config.tenant_id)
|
|
35
35
|
end
|