lex-tasker 0.2.1 → 0.3.1
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/.github/workflows/ci.yml +16 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +36 -22
- data/CHANGELOG.md +53 -0
- data/CLAUDE.md +82 -0
- data/Dockerfile +1 -1
- data/Gemfile +16 -1
- data/README.md +45 -2
- data/Rakefile +2 -0
- data/docker_deploy.rb +1 -0
- data/lex-tasker.gemspec +16 -12
- data/lib/legion/extensions/tasker/actors/check_subtask.rb +20 -14
- data/lib/legion/extensions/tasker/actors/fetch_delayed.rb +23 -17
- data/lib/legion/extensions/tasker/actors/fetch_delayed_push.rb +26 -20
- data/lib/legion/extensions/tasker/actors/log.rb +14 -8
- data/lib/legion/extensions/tasker/actors/task_manager.rb +20 -14
- data/lib/legion/extensions/tasker/actors/updater.rb +20 -14
- data/lib/legion/extensions/tasker/client.rb +29 -0
- data/lib/legion/extensions/tasker/helpers/task_finder.rb +98 -0
- data/lib/legion/extensions/tasker/runners/check_subtask.rb +92 -80
- data/lib/legion/extensions/tasker/runners/fetch_delayed.rb +76 -60
- data/lib/legion/extensions/tasker/runners/log.rb +47 -41
- data/lib/legion/extensions/tasker/runners/task_manager.rb +12 -5
- data/lib/legion/extensions/tasker/runners/updater.rb +25 -22
- data/lib/legion/extensions/tasker/transport/exchanges/task.rb +10 -4
- data/lib/legion/extensions/tasker/transport/messages/fetch_delayed.rb +17 -7
- data/lib/legion/extensions/tasker/transport/queues/check_subtask.rb +18 -12
- data/lib/legion/extensions/tasker/transport/queues/fetch_delayed.rb +20 -15
- data/lib/legion/extensions/tasker/transport/queues/lex_register.rb +15 -9
- data/lib/legion/extensions/tasker/transport/queues/subtask.rb +12 -6
- data/lib/legion/extensions/tasker/transport/queues/task_log.rb +12 -6
- data/lib/legion/extensions/tasker/transport/queues/task_mananger.rb +15 -9
- data/lib/legion/extensions/tasker/transport/queues/updater.rb +12 -6
- data/lib/legion/extensions/tasker/transport.rb +31 -24
- data/lib/legion/extensions/tasker/version.rb +3 -1
- data/lib/legion/extensions/tasker.rb +2 -4
- metadata +54 -43
- data/.circleci/config.yml +0 -39
- data/Gemfile.lock +0 -69
- data/bitbucket-pipelines.yml +0 -19
- data/lib/legion/extensions/tasker/helpers/base.rb +0 -11
- data/lib/legion/extensions/tasker/helpers/fetch_delayed.rb +0 -66
- data/lib/legion/extensions/tasker/helpers/find_subtask.rb +0 -49
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Tasker
|
|
6
|
+
module Helpers
|
|
7
|
+
module TaskFinder
|
|
8
|
+
def find_trigger(runner_class:, function:, **)
|
|
9
|
+
cache_key = "find_trigger:#{runner_class}:#{function}"
|
|
10
|
+
cached = cache_get(cache_key)
|
|
11
|
+
return cached unless cached.nil?
|
|
12
|
+
|
|
13
|
+
result = Legion::Data::Model::Function
|
|
14
|
+
.join(:runners, id: :runner_id)
|
|
15
|
+
.where(Sequel[:functions][:name] => function,
|
|
16
|
+
Sequel[:runners][:namespace] => runner_class)
|
|
17
|
+
.select(Sequel[:functions][:id].as(:function_id),
|
|
18
|
+
Sequel[:functions][:runner_id],
|
|
19
|
+
Sequel[:runners][:namespace])
|
|
20
|
+
.first
|
|
21
|
+
|
|
22
|
+
cache_set(cache_key, result) if result
|
|
23
|
+
result
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def find_subtasks(trigger_id:, **)
|
|
27
|
+
cache_key = "find_subtasks:#{trigger_id}"
|
|
28
|
+
cached = cache_get(cache_key)
|
|
29
|
+
return cached unless cached.nil?
|
|
30
|
+
|
|
31
|
+
results = subtask_query(trigger_id).all.map do |row|
|
|
32
|
+
row[:runner_routing_key] = "#{row[:exchange]}.#{row[:queue]}.#{row[:function]}"
|
|
33
|
+
row
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
cache_set(cache_key, results, ttl: 5) if results.is_a?(Array) && results.any?
|
|
37
|
+
results
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def find_delayed(**)
|
|
41
|
+
Legion::Data::Model::Task
|
|
42
|
+
.join(:functions, id: :function_id)
|
|
43
|
+
.join(:runners, id: Sequel[:functions][:runner_id])
|
|
44
|
+
.join(:extensions, id: Sequel[:runners][:extension_id])
|
|
45
|
+
.left_join(:relationships, id: Sequel[:tasks][:relationship_id])
|
|
46
|
+
.where(Sequel[:tasks][:status] => 'task.delayed')
|
|
47
|
+
.select(
|
|
48
|
+
Sequel[:tasks][:id],
|
|
49
|
+
Sequel[:tasks][:relationship_id],
|
|
50
|
+
Sequel[:tasks][:function_id],
|
|
51
|
+
Sequel[:tasks][:created],
|
|
52
|
+
Sequel[:relationships][:delay].as(:relationship_delay),
|
|
53
|
+
Sequel[:relationships][:chain_id],
|
|
54
|
+
Sequel[:functions][:name].as(:function_name),
|
|
55
|
+
Sequel[:runners][:namespace].as(:runner_class),
|
|
56
|
+
Sequel[:runners][:id].as(:runner_id),
|
|
57
|
+
Sequel[:runners][:queue],
|
|
58
|
+
Sequel[:extensions][:exchange],
|
|
59
|
+
Sequel[:tasks][:task_delay]
|
|
60
|
+
).all.map do |task|
|
|
61
|
+
task[:runner_routing_key] = "#{task[:exchange]}.#{task[:queue]}.#{task[:function_name]}"
|
|
62
|
+
task
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def subtask_query(trigger_id)
|
|
69
|
+
Legion::Data::Model::Relationship
|
|
70
|
+
.join(:functions, id: :action_id)
|
|
71
|
+
.join(:runners, id: Sequel[:functions][:runner_id])
|
|
72
|
+
.join(:extensions, id: Sequel[:runners][:extension_id])
|
|
73
|
+
.where(Sequel[:relationships][:trigger_id] => trigger_id,
|
|
74
|
+
Sequel[:relationships][:active] => true)
|
|
75
|
+
.select(
|
|
76
|
+
Sequel[:relationships][:id].as(:relationship_id),
|
|
77
|
+
Sequel[:relationships][:debug],
|
|
78
|
+
Sequel[:relationships][:chain_id],
|
|
79
|
+
Sequel[:relationships][:allow_new_chains],
|
|
80
|
+
Sequel[:relationships][:delay],
|
|
81
|
+
Sequel[:relationships][:trigger_id],
|
|
82
|
+
Sequel[:relationships][:action_id],
|
|
83
|
+
Sequel[:relationships][:conditions],
|
|
84
|
+
Sequel[:relationships][:transformation],
|
|
85
|
+
Sequel[:runners][:namespace],
|
|
86
|
+
Sequel[:runners][:id].as(:runner_id),
|
|
87
|
+
Sequel[:runners][:queue],
|
|
88
|
+
Sequel[:runners][:namespace].as(:runner_class),
|
|
89
|
+
Sequel[:functions][:id].as(:function_id),
|
|
90
|
+
Sequel[:functions][:name].as(:function),
|
|
91
|
+
Sequel[:extensions][:exchange]
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -1,96 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'legion/transport/messages/subtask'
|
|
2
4
|
|
|
3
|
-
module Legion
|
|
4
|
-
module
|
|
5
|
-
module
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Tasker
|
|
8
|
+
module Runners
|
|
9
|
+
module CheckSubtask
|
|
10
|
+
include Legion::Extensions::Helpers::Lex
|
|
11
|
+
include Legion::Extensions::Tasker::Helpers::TaskFinder
|
|
12
|
+
|
|
13
|
+
def check_subtasks(runner_class:, function:, **opts)
|
|
14
|
+
trigger = find_trigger(runner_class: runner_class, function: function)
|
|
15
|
+
return { success: true, subtasks: 0 } unless trigger
|
|
16
|
+
|
|
17
|
+
find_subtasks(trigger_id: trigger[:function_id]).each do |relationship|
|
|
18
|
+
next unless chain_matches?(relationship, opts)
|
|
19
|
+
|
|
20
|
+
task_hash = build_task_hash(relationship, opts)
|
|
21
|
+
dispatch_task(task_hash, trigger, opts)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def chain_matches?(relationship, opts)
|
|
26
|
+
return true if relationship[:allow_new_chains]
|
|
8
27
|
|
|
9
|
-
|
|
10
|
-
|
|
28
|
+
!relationship[:chain_id].nil? && opts.key?(:chain_id) && relationship[:chain_id] == opts[:chain_id]
|
|
29
|
+
end
|
|
11
30
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
31
|
+
def build_task_hash(relationship, opts)
|
|
32
|
+
task_hash = relationship.dup
|
|
33
|
+
task_hash[:status] = relationship[:delay].to_i.zero? ? 'conditioner.queued' : 'task.delayed'
|
|
34
|
+
task_hash[:payload] = opts
|
|
35
|
+
task_hash[:master_id] = resolve_master_id(opts)
|
|
36
|
+
task_hash[:parent_id] = opts[:task_id] if opts.key?(:task_id)
|
|
37
|
+
task_hash[:routing_key] = subtask_routing_key(relationship)
|
|
38
|
+
task_hash
|
|
17
39
|
end
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
def resolve_master_id(opts)
|
|
42
|
+
return opts[:master_id] if opts.key?(:master_id)
|
|
43
|
+
return opts[:parent_id] if opts.key?(:parent_id)
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
task_hash[:master_id] = opts[:master_id]
|
|
25
|
-
elsif opts.key? :parent_id
|
|
26
|
-
task_hash[:master_id] = opts[:parent_id]
|
|
27
|
-
elsif opts.key? :task_id
|
|
28
|
-
task_hash[:master_id] = opts[:task_id]
|
|
45
|
+
opts[:task_id] if opts.key?(:task_id)
|
|
29
46
|
end
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
if opts[:result].is_a? Array
|
|
41
|
-
opts[:result].each do |result|
|
|
42
|
-
send_task(results: result,
|
|
43
|
-
trigger_runner_id: trigger[:runner_id],
|
|
44
|
-
trigger_function_id: trigger[:function_id],
|
|
45
|
-
**task_hash)
|
|
48
|
+
def subtask_routing_key(relationship)
|
|
49
|
+
if relationship[:conditions].is_a?(String) && relationship[:conditions].length > 4
|
|
50
|
+
'task.subtask.conditioner'
|
|
51
|
+
elsif relationship[:transformation].is_a?(String) && relationship[:transformation].length > 4
|
|
52
|
+
'task.subtask.transformation'
|
|
53
|
+
else
|
|
54
|
+
relationship[:runner_routing_key]
|
|
46
55
|
end
|
|
47
|
-
else
|
|
48
|
-
results = if opts[:results].is_a? Hash
|
|
49
|
-
opts[:results]
|
|
50
|
-
elsif opts[:result].is_a? Hash
|
|
51
|
-
opts[:result]
|
|
52
|
-
else
|
|
53
|
-
opts
|
|
54
|
-
end
|
|
55
|
-
send_task(
|
|
56
|
-
results: results,
|
|
57
|
-
trigger_runner_id: trigger[:runner_id],
|
|
58
|
-
trigger_function_id: trigger[:function_id],
|
|
59
|
-
**task_hash
|
|
60
|
-
)
|
|
61
56
|
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
58
|
+
def dispatch_task(task_hash, trigger, opts)
|
|
59
|
+
trigger_info = { trigger_runner_id: trigger[:runner_id], trigger_function_id: trigger[:function_id] }
|
|
60
|
+
results_value = opts[:result] || opts[:results]
|
|
61
|
+
|
|
62
|
+
if results_value.is_a?(Array)
|
|
63
|
+
results_value.each do |result|
|
|
64
|
+
send_task(results: result, **trigger_info, **task_hash)
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
send_task(results: resolve_results(opts), **trigger_info, **task_hash)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def resolve_results(opts)
|
|
72
|
+
return opts[:results] if opts[:results].is_a?(Hash)
|
|
73
|
+
return opts[:result] if opts[:result].is_a?(Hash)
|
|
74
|
+
|
|
75
|
+
opts
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def send_task(**opts)
|
|
79
|
+
opts[:results] = opts[:result] if opts.key?(:result) && !opts.key?(:results)
|
|
80
|
+
opts[:success] = if opts.key?(:result) && opts.key?(:success)
|
|
81
|
+
opts[:result][:success]
|
|
82
|
+
elsif opts.key?(:success)
|
|
83
|
+
opts[:success]
|
|
84
|
+
else
|
|
85
|
+
1
|
|
86
|
+
end
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
opts[:task_id] = insert_task(**opts)
|
|
89
|
+
return { status: true } unless opts[:delay].zero?
|
|
90
|
+
|
|
91
|
+
Legion::Transport::Messages::SubTask.new(**opts).publish
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def insert_task(relationship_id:, function_id:, **opts)
|
|
95
|
+
status = opts.fetch(:status, 'task.queued')
|
|
96
|
+
master_id = opts[:master_id]
|
|
97
|
+
parent_id = opts[:parent_id]
|
|
98
|
+
|
|
99
|
+
insert_hash = { relationship_id: relationship_id, function_id: function_id, status: status }
|
|
100
|
+
insert_hash[:master_id] = master_id.is_a?(Integer) ? master_id : (parent_id if parent_id.is_a?(Integer))
|
|
101
|
+
insert_hash[:parent_id] = parent_id if parent_id.is_a?(Integer)
|
|
102
|
+
insert_hash[:payload] = json_dump(opts)
|
|
103
|
+
Legion::Data::Model::Task.insert(insert_hash)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
94
106
|
end
|
|
95
107
|
end
|
|
96
108
|
end
|
|
@@ -1,71 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
module FetchDelayed
|
|
3
|
-
extend Legion::Extensions::Tasker::Helpers::FetchDelayed
|
|
4
|
-
include Legion::Extensions::Helpers::Task
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Tasker
|
|
6
|
+
module Runners
|
|
7
|
+
module FetchDelayed
|
|
8
|
+
include Legion::Extensions::Tasker::Helpers::TaskFinder
|
|
9
|
+
include Legion::Extensions::Helpers::Task
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
def fetch(**_opts)
|
|
12
|
+
find_delayed.each do |task|
|
|
13
|
+
next if delayed_by?(task[:relationship_delay], task[:created])
|
|
14
|
+
next if delayed_by?(task[:task_delay], task[:created])
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
runner_id: task[:runner_id],
|
|
22
|
-
runner_class: task[:runner_class],
|
|
23
|
-
task_id: task[:id],
|
|
24
|
-
exchange: task[:exchange],
|
|
25
|
-
queue: task[:queue]
|
|
26
|
-
}
|
|
16
|
+
subtask_hash = build_delayed_hash(task)
|
|
17
|
+
send_task(**subtask_hash)
|
|
18
|
+
update_delayed_status(task[:id], subtask_hash[:routing_key])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
def delayed_by?(delay, created)
|
|
23
|
+
delay.is_a?(Integer) && delay.positive? && Time.now < created + delay
|
|
24
|
+
end
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
def build_delayed_hash(task)
|
|
27
|
+
subtask_hash = {
|
|
28
|
+
relationship_id: task[:relationship_id],
|
|
29
|
+
chain_id: task[:chain_id],
|
|
30
|
+
function_id: task[:function_id],
|
|
31
|
+
function: task[:function_name],
|
|
32
|
+
runner_id: task[:runner_id],
|
|
33
|
+
runner_class: task[:runner_class],
|
|
34
|
+
task_id: task[:id],
|
|
35
|
+
exchange: task[:exchange],
|
|
36
|
+
queue: task[:queue]
|
|
37
|
+
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
task_update(task[:id], 'transformer.queued')
|
|
45
|
-
else
|
|
46
|
-
task_update(task[:id], 'task.queued')
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
39
|
+
subtask_hash[:conditions] = task[:conditions] if task[:conditions].is_a?(String)
|
|
40
|
+
subtask_hash[:transformation] = task[:transformation] if task[:transformation].is_a?(String)
|
|
41
|
+
subtask_hash[:routing_key] = delayed_routing_key(task)
|
|
42
|
+
subtask_hash
|
|
43
|
+
end
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
log.debug 'pushing delayed task to worker'
|
|
61
|
-
Legion::Transport::Messages::Task.new(**opts).publish
|
|
62
|
-
end
|
|
45
|
+
def delayed_routing_key(task)
|
|
46
|
+
if task[:conditions].is_a?(String) && task[:conditions].length > 4
|
|
47
|
+
'task.subtask.conditioner'
|
|
48
|
+
elsif task[:transformation].is_a?(String) && task[:transformation].length > 4
|
|
49
|
+
'task.subtask.transformation'
|
|
50
|
+
else
|
|
51
|
+
task[:runner_routing_key]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
def update_delayed_status(task_id, routing_key)
|
|
56
|
+
status = case routing_key
|
|
57
|
+
when 'task.subtask.conditioner' then 'conditioner.queued'
|
|
58
|
+
when 'task.subtask.transformation' then 'transformer.queued'
|
|
59
|
+
else 'task.queued'
|
|
60
|
+
end
|
|
61
|
+
task_update(task_id, status)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def send_task(**opts)
|
|
65
|
+
opts[:results] = opts[:result] if opts.key?(:result) && !opts.key?(:results)
|
|
66
|
+
opts[:success] = if opts.key?(:result) && opts.key?(:success)
|
|
67
|
+
opts[:result][:success]
|
|
68
|
+
elsif opts.key?(:success)
|
|
69
|
+
opts[:success]
|
|
70
|
+
else
|
|
71
|
+
1
|
|
72
|
+
end
|
|
73
|
+
log.debug 'pushing delayed task to worker'
|
|
74
|
+
Legion::Transport::Messages::Task.new(**opts).publish
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def push(**_opts)
|
|
78
|
+
Legion::Extensions::Tasker::Transport::Messages::FetchDelayed.new.publish
|
|
79
|
+
{ success: true }
|
|
80
|
+
end
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
include Legion::Extensions::Helpers::Lex
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
70
86
|
end
|
|
71
87
|
end
|
|
@@ -1,49 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Tasker
|
|
8
|
+
module Runners
|
|
9
|
+
module Log
|
|
10
|
+
include Legion::Extensions::Helpers::Lex
|
|
11
|
+
|
|
12
|
+
def add_log(task_id:, entry:, function: nil, runner_class: nil, **opts)
|
|
13
|
+
entry = ::JSON.dump(entry) unless entry.is_a? String
|
|
14
|
+
insert = { task_id: task_id, entry: entry }
|
|
15
|
+
if opts.key?(:node_id)
|
|
16
|
+
insert[:node_id] = opts[:node_id]
|
|
17
|
+
elsif opts.key?(:name)
|
|
18
|
+
node = Legion::Data::Model::Node.where(name: opts[:name]).first
|
|
19
|
+
insert[:node_id] = node.values[:id] unless node.nil?
|
|
20
|
+
end
|
|
21
|
+
insert[:function_id] = opts[:function_id] if opts.key? :function_id
|
|
22
|
+
|
|
23
|
+
unless function.nil? && runner_class.nil?
|
|
24
|
+
runner = Legion::Data::Model::Runner.where(namespace: runner_class).first
|
|
25
|
+
insert[:function_id] = runner.functions_dataset.where(name: function).first.values[:id] unless runner.nil?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
id = Legion::Data::Model::TaskLog.insert(insert)
|
|
29
|
+
|
|
30
|
+
{ success: !id.nil?, id: id }
|
|
21
31
|
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
id = Legion::Data::Model::TaskLog.insert(insert)
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
delete = Legion::Data::Model::TaskLog[id].delete
|
|
31
|
-
{ success: delete.positive?, count: delete, deleted_id: id }
|
|
32
|
-
end
|
|
33
|
+
def delete_log(id:, **_opts)
|
|
34
|
+
delete = Legion::Data::Model::TaskLog[id].delete
|
|
35
|
+
{ success: delete.positive?, count: delete, deleted_id: id }
|
|
36
|
+
end
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
def delete_task_logs(task_id:, **_opts)
|
|
39
|
+
delete = Legion::Data::Model::TaskLog.where(task_id: task_id).delete
|
|
40
|
+
{ success: delete.positive?, count: delete, deleted_task_id: task_id }
|
|
41
|
+
end
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
def delete_node_logs(node_id:, **_opts)
|
|
44
|
+
delete = Legion::Data::Model::TaskLog.where(node_id: node_id).delete
|
|
45
|
+
{ success: delete.positive?, count: delete, deleted_node_id: node_id }
|
|
46
|
+
end
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
def delete_all(**_opts)
|
|
49
|
+
delete = Legion::Data::Model::TaskLog.dataset.delete
|
|
50
|
+
{ success: delete.positive?, count: delete }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
47
53
|
end
|
|
48
54
|
end
|
|
49
55
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Legion
|
|
2
4
|
module Extensions
|
|
3
5
|
module Tasker
|
|
@@ -5,18 +7,23 @@ module Legion
|
|
|
5
7
|
module TaskManager
|
|
6
8
|
def purge_old(age: 31, limit: 100, status: 'task.completed', **_opts)
|
|
7
9
|
log.debug("purging old completed tasks with an age > #{age} days, limit: #{limit}")
|
|
10
|
+
cutoff = Time.now - (age * 86_400)
|
|
8
11
|
dataset = Legion::Data::Model::Task
|
|
9
|
-
.where(Sequel.lit(
|
|
12
|
+
.where(Sequel.lit('created <= ?', cutoff))
|
|
10
13
|
.limit(limit)
|
|
11
|
-
dataset.where(status: status) unless ['*', nil, ''].include?
|
|
12
|
-
log.debug "Deleting #{dataset.count} records" if dataset.
|
|
14
|
+
dataset = dataset.where(status: status) unless ['*', nil, ''].include?(status)
|
|
15
|
+
log.debug "Deleting #{dataset.count} records" if dataset.any?
|
|
13
16
|
dataset&.delete
|
|
14
17
|
end
|
|
15
18
|
|
|
16
|
-
def expire_queued(age: 1, limit: 10, **)
|
|
17
|
-
|
|
19
|
+
def expire_queued(age: 1, limit: 10, **)
|
|
20
|
+
cutoff = Time.now - (age * 3600)
|
|
21
|
+
dataset = Legion::Data::Model::Task
|
|
18
22
|
.where(status: ['conditioner.queued', 'transformer.queued', 'task.queued'])
|
|
23
|
+
.where(Sequel.lit('created <= ?', cutoff))
|
|
19
24
|
.limit(limit)
|
|
25
|
+
count = dataset.update(status: 'task.expired')
|
|
26
|
+
{ success: true, expired: count }
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
include Legion::Extensions::Helpers::Task
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
module Runners
|
|
3
|
-
module Updater
|
|
4
|
-
include Legion::Extensions::Helpers::Lex
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Tasker
|
|
6
|
+
module Runners
|
|
7
|
+
module Updater
|
|
8
|
+
include Legion::Extensions::Helpers::Lex
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
def update_status(task_id:, **opts)
|
|
11
|
+
task = Legion::Data::Model::Task[task_id]
|
|
12
|
+
return { success: false, changed: false, task_id: task_id, message: 'task nil' } if task.nil? || task.values.nil?
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
update_hash = {}
|
|
15
|
+
%i[status function_args payload results].each do |column|
|
|
16
|
+
next unless opts.key? column
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
task.update(update_hash)
|
|
18
|
+
update_hash[column] = if opts[column].is_a? String
|
|
19
|
+
opts[column]
|
|
20
|
+
else
|
|
21
|
+
to_json opts[column]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
return { success: true, changed: false, task_id: task_id } if update_hash.none?
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
task.update(update_hash)
|
|
27
|
+
|
|
28
|
+
{ success: true, changed: true, task_id: task_id, updates: update_hash }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
28
31
|
end
|
|
29
32
|
end
|
|
30
33
|
end
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Tasker
|
|
6
|
+
module Transport
|
|
7
|
+
module Exchanges
|
|
8
|
+
class Tasker < Legion::Transport::Exchanges::Task
|
|
9
|
+
end
|
|
10
|
+
end
|
|
5
11
|
end
|
|
6
12
|
end
|
|
7
13
|
end
|