lex-tasker 0.2.1 → 0.3.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +16 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +36 -22
  5. data/CHANGELOG.md +43 -0
  6. data/CLAUDE.md +83 -0
  7. data/Dockerfile +1 -1
  8. data/Gemfile +9 -1
  9. data/README.md +34 -2
  10. data/Rakefile +2 -0
  11. data/docker_deploy.rb +1 -0
  12. data/lex-tasker.gemspec +9 -13
  13. data/lib/legion/extensions/tasker/actors/check_subtask.rb +20 -14
  14. data/lib/legion/extensions/tasker/actors/fetch_delayed.rb +23 -17
  15. data/lib/legion/extensions/tasker/actors/fetch_delayed_push.rb +26 -20
  16. data/lib/legion/extensions/tasker/actors/log.rb +14 -8
  17. data/lib/legion/extensions/tasker/actors/task_manager.rb +20 -14
  18. data/lib/legion/extensions/tasker/actors/updater.rb +20 -14
  19. data/lib/legion/extensions/tasker/client.rb +29 -0
  20. data/lib/legion/extensions/tasker/helpers/task_finder.rb +98 -0
  21. data/lib/legion/extensions/tasker/runners/check_subtask.rb +92 -80
  22. data/lib/legion/extensions/tasker/runners/fetch_delayed.rb +76 -60
  23. data/lib/legion/extensions/tasker/runners/log.rb +47 -41
  24. data/lib/legion/extensions/tasker/runners/task_manager.rb +12 -5
  25. data/lib/legion/extensions/tasker/runners/updater.rb +25 -22
  26. data/lib/legion/extensions/tasker/transport/exchanges/task.rb +10 -4
  27. data/lib/legion/extensions/tasker/transport/messages/fetch_delayed.rb +17 -7
  28. data/lib/legion/extensions/tasker/transport/queues/check_subtask.rb +18 -12
  29. data/lib/legion/extensions/tasker/transport/queues/fetch_delayed.rb +20 -15
  30. data/lib/legion/extensions/tasker/transport/queues/lex_register.rb +15 -9
  31. data/lib/legion/extensions/tasker/transport/queues/subtask.rb +12 -6
  32. data/lib/legion/extensions/tasker/transport/queues/task_log.rb +12 -6
  33. data/lib/legion/extensions/tasker/transport/queues/task_mananger.rb +15 -9
  34. data/lib/legion/extensions/tasker/transport/queues/updater.rb +12 -6
  35. data/lib/legion/extensions/tasker/transport.rb +31 -24
  36. data/lib/legion/extensions/tasker/version.rb +3 -1
  37. data/lib/legion/extensions/tasker.rb +2 -4
  38. metadata +17 -104
  39. data/.circleci/config.yml +0 -39
  40. data/Gemfile.lock +0 -69
  41. data/bitbucket-pipelines.yml +0 -19
  42. data/lib/legion/extensions/tasker/helpers/base.rb +0 -11
  43. data/lib/legion/extensions/tasker/helpers/fetch_delayed.rb +0 -66
  44. 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 = "tasker:find_trigger:#{runner_class}:#{function}"
10
+ cached = Legion::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
+ Legion::Cache.set(cache_key, result) if result
23
+ result
24
+ end
25
+
26
+ def find_subtasks(trigger_id:, **)
27
+ cache_key = "tasker:find_subtasks:#{trigger_id}"
28
+ cached = Legion::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
+ Legion::Cache.set(cache_key, results, 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::Extensions::Tasker
4
- module Runners
5
- module CheckSubtask
6
- include Legion::Extensions::Helpers::Lex
7
- extend Legion::Extensions::Tasker::Helpers::FindSubtask
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
- def check_subtasks(runner_class:, function:, **opts)
10
- trigger = find_trigger(runner_class: runner_class, function: function)
28
+ !relationship[:chain_id].nil? && opts.key?(:chain_id) && relationship[:chain_id] == opts[:chain_id]
29
+ end
11
30
 
12
- find_subtasks(trigger_id: trigger[:function_id]).each do |relationship|
13
- unless relationship[:allow_new_chains]
14
- next if relationship[:chain_id].nil?
15
- next unless opts.key? :chain_id
16
- next unless relationship[:chain_id] == opts[:chain_id]
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
- task_hash = relationship
20
- task_hash[:status] = relationship[:delay].zero? ? 'conditioner.queued' : 'task.delayed'
21
- task_hash[:payload] = opts
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
- if opts.key? :master_id
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
- task_hash[:parent_id] = opts[:task_id] if opts.key? :task_id
32
- task_hash[:routing_key] = if relationship[:conditions].is_a?(String) && relationship[:conditions].length > 4
33
- 'task.subtask.conditioner'
34
- elsif relationship[:transformation].is_a?(String) && relationship[:transformation].length > 4 # rubocop:disable Layout/LineLength
35
- 'task.subtask.transformation'
36
- else
37
- relationship[:runner_routing_key]
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
- def send_task(**opts)
66
- opts[:results] = opts[:result] if opts.key?(:result) && !opts.key?(:results)
67
- opts[:success] = if opts.key?(:result) && opts.key?(:success)
68
- opts[:result][:success]
69
- elsif opts.key?(:success)
70
- opts[:success]
71
- else
72
- 1
73
- end
74
-
75
- # opts[:task_id] = Legion::Runner::Status.generate_task_id(**opts)[:task_id]
76
- opts[:task_id] = insert_task(**opts)
77
- return { status: true } unless opts[:delay].zero?
78
-
79
- Legion::Transport::Messages::SubTask.new(**opts).publish
80
- end
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
- def insert_task(relationship_id:, function_id:, status: 'task.queued', master_id: nil, parent_id: nil, **opts)
83
- insert_hash = { relationship_id: relationship_id, function_id: function_id, status: status }
84
- insert_hash[:master_id] = if master_id.is_a? Integer
85
- master_id
86
- elsif parent_id.is_a? Integer
87
- parent_id
88
- end
89
- insert_hash[:parent_id] = parent_id if parent_id.is_a? Integer
90
- insert_hash[:payload] = Legion::JSON.dump(opts)
91
- # insert_hash[:function_args] = nil
92
- # insert_hash[:results] = nil
93
- Legion::Data::Model::Task.insert(insert_hash)
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] = Legion::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
- module Legion::Extensions::Tasker::Runners
2
- module FetchDelayed
3
- extend Legion::Extensions::Tasker::Helpers::FetchDelayed
4
- include Legion::Extensions::Helpers::Task
1
+ # frozen_string_literal: true
5
2
 
6
- def fetch(**_opts)
7
- find_delayed.each do |task|
8
- if task[:relationship_delay].is_a?(Integer) && task[:relationship_delay].positive?
9
- next if Time.now < task[:created] + task[:relationship_delay] # rubocop:disable Style/SoleNestedConditional
10
- end
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
- if task[:task_delay].is_a?(Integer) && task[:task_delay].positive?
13
- next if Time.now < task[:created] + task[:task_delay] # rubocop:disable Style/SoleNestedConditional
14
- end
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
- subtask_hash = {
17
- relationship_id: task[:relationship_id],
18
- chain_id: task[:chain_id],
19
- function_id: task[:function_id],
20
- function: task[:function_name],
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
- subtask_hash[:conditions] = task[:conditions] if task[:conditions].is_a?(String)
29
- subtask_hash[:transformation] = task[:transformation] if task[:transformation].is_a?(String)
22
+ def delayed_by?(delay, created)
23
+ delay.is_a?(Integer) && delay.positive? && Time.now < created + delay
24
+ end
30
25
 
31
- subtask_hash[:routing_key] = if task[:conditions].is_a?(String) && task[:conditions].length > 4
32
- 'task.subtask.conditioner'
33
- elsif task[:transformation].is_a?(String) && task[:transformation].length > 4
34
- 'task.subtask.transformation'
35
- else
36
- task[:runner_routing_key]
37
- end
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
- send_task(**subtask_hash)
40
- case subtask_hash[:routing_key]
41
- when 'task.subtask.conditioner'
42
- task_update(task[:id], 'conditioner.queued')
43
- when 'task.subtask.transformation'
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
- def send_task(**opts)
52
- opts[:results] = opts[:result] if opts.key?(:result) && !opts.key?(:results)
53
- opts[:success] = if opts.key?(:result) && opts.key?(:success)
54
- opts[:result][:success]
55
- elsif opts.key?(:success)
56
- opts[:success]
57
- else
58
- 1
59
- end
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
- def push(**_opts)
65
- Legion::Extensions::Tasker::Transport::Messages::FetchDelayed.new.publish
66
- { success: true }
67
- end
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
- include Legion::Extensions::Helpers::Lex
82
+ include Legion::Extensions::Helpers::Lex
83
+ end
84
+ end
85
+ end
70
86
  end
71
87
  end
@@ -1,49 +1,55 @@
1
- module Legion::Extensions::Tasker
2
- module Runners
3
- module Log
4
- include Legion::Extensions::Helpers::Lex
5
-
6
- def add_log(task_id:, entry:, function: nil, runner_class: nil, **opts)
7
- entry = JSON.dump(entry) unless entry.is_a? String
8
- insert = { task_id: task_id, entry: entry }
9
- if opts.key?(:node_id)
10
- insert[:node_id] = payload[:node_id]
11
- elsif opts.key?(:name)
12
- node = Legion::Data::Model::Node.where(opts[:name]).first
13
- insert[:node_id] = node.values[:id] unless node.nil?
14
- end
15
- insert[:function_id] = opts[:function_id] if opts.key? :function_id
16
-
17
- unless function.nil? && runner_class.nil?
18
- runner = Legion::Data::Model::Runner.where(namespace: runner_class).first
19
- unless runner.values.nil?
20
- insert[:function_id] = runner.functions_dataset.where(name: function).first.values[:id]
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
- { success: !id.nil?, id: id }
27
- end
28
-
29
- def delete_log(id:, **_opts)
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
- def delete_task_logs(task_id:, **_opts)
35
- delete = Legion::Data::Model::TaskLog.where(task_id: task_id).delete
36
- { success: delete.positive?, count: delete, deleted_task_id: task_id }
37
- end
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
- def delete_node_logs(node_id:, **_opts)
40
- delete = Legion::Data::Model::TaskLog.where(node_id: node_id).delete
41
- { success: delete.positive?, count: delete, deleted_node_id: node_id }
42
- end
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
- def delete_all(**_opts)
45
- delete = Legion::Data::Model::TaskLog.all.delete
46
- { success: delete.positive?, count: delete }
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("created <= DATE_SUB(SYSDATE(), INTERVAL #{age} DAY)"))
12
+ .where(Sequel.lit('created <= ?', cutoff))
10
13
  .limit(limit)
11
- dataset.where(status: status) unless ['*', nil, ''].include? status
12
- log.debug "Deleting #{dataset.count} records" if dataset.count.positive?
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, **) # rubocop:disable Lint/UnusedMethodArgument
17
- dataset = Legion::Data::Model::Task # rubocop:disable Lint/UselessAssignment
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
- module Legion::Extensions::Tasker
2
- module Runners
3
- module Updater
4
- include Legion::Extensions::Helpers::Lex
1
+ # frozen_string_literal: true
5
2
 
6
- def update_status(task_id:, **opts)
7
- task = Legion::Data::Model::Task[task_id]
8
- if task.nil? || task.values.nil?
9
- return { success: false, changed: false, task_id: task_id, message: 'task nil' }
10
- end
3
+ module Legion
4
+ module Extensions
5
+ module Tasker
6
+ module Runners
7
+ module Updater
8
+ include Legion::Extensions::Helpers::Lex
11
9
 
12
- log.unknown task.class
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
- update_hash = {}
15
- %i[status function_args payload results].each do |column|
16
- next unless opts.key? column
14
+ update_hash = {}
15
+ %i[status function_args payload results].each do |column|
16
+ next unless opts.key? column
17
17
 
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
- { success: true, changed: false, task_id: task_id } if update_hash.count.zero?
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
- { success: true, changed: true, task_id: task_id, updates: update_hash }
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
- module Legion::Extensions::Tasker
2
- module Transport
3
- module Exchanges
4
- class Tasker < Legion::Transport::Exchanges::Task
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