isomorfeus-operation 2.2.11 → 2.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.
- checksums.yaml +4 -4
- data/README.md +2 -3
- data/lib/isomorfeus/operation/config.rb +23 -0
- data/lib/isomorfeus/operation/daily_task.rb +23 -0
- data/lib/isomorfeus/operation/deferred_task.rb +22 -0
- data/lib/isomorfeus/operation/generic_class_api.rb +94 -0
- data/lib/isomorfeus/operation/handler/operation_handler.rb +50 -30
- data/lib/isomorfeus/operation/init_timer_tasks.rb +13 -0
- data/lib/isomorfeus/operation/run_task.rb +97 -0
- data/lib/isomorfeus/operation/version.rb +1 -1
- data/lib/isomorfeus-operation.rb +11 -5
- data/lib/isomorfeus_operation/lucid_operation/mixin.rb +27 -57
- data/lib/isomorfeus_operation/{lucid_quick_op → lucid_simple_operation}/base.rb +2 -2
- data/lib/isomorfeus_operation/lucid_simple_operation/mixin.rb +50 -0
- metadata +47 -14
- data/lib/isomorfeus_operation/lucid_quick_op/mixin.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa334a5da0534716ceda0a03d2661690b5a56afca7e908c099745ce10f30b933
|
4
|
+
data.tar.gz: 10ac1f1ea1053ea12e142ea52e5a1908c886d89d20e9c7d6c8ba8891bc1c4291
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5edfbd1b5d635459936fe154ffc9736b5ed304cadd683cd6b1fe6501121cc809c3ee933e56e3fc884bd7001c140a7bd3fcd9349ae998773a019d1337e01fbebf
|
7
|
+
data.tar.gz: acd1fda633bf585a757507863823b204394a7fd8ed9671b8324a282aeeb00b42ce180ac43a408f3cd89b23926a93d49fe14e1a05fc12235cb537669bb154d634
|
data/README.md
CHANGED
@@ -10,7 +10,6 @@ Operations use Props like other parts of the system.
|
|
10
10
|
See [the isomorfeus-preact props documentation](https://github.com/isomorfeus/isomorfeus-preact/blob/master/docs/props.md#prop-declaration).
|
11
11
|
|
12
12
|
There are 3 kinds of Operations:
|
13
|
-
- [
|
14
|
-
- [LucidOperation](https://github.com/isomorfeus/isomorfeus-project/blob/master/isomorfeus-operation/docs/operation.md) - For complex multi-stepped operations, always executed on the server.
|
13
|
+
- [LucidSimpleOperation](https://github.com/isomorfeus/isomorfeus-project/blob/master/isomorfeus-operation/docs/simple_operation.md) - Simple operation, always executed on the server, also deferred or daily.
|
14
|
+
- [LucidOperation](https://github.com/isomorfeus/isomorfeus-project/blob/master/isomorfeus-operation/docs/operation.md) - For complex multi-stepped operations, always executed on the server, also deferred or daily.
|
15
15
|
- [LucidLocalOperation](https://github.com/isomorfeus/isomorfeus-project/blob/master/isomorfeus-operation/docs/operation.md) - For complex multi-stepped operations, always executed locally.
|
16
|
-
|
@@ -11,6 +11,8 @@ module Isomorfeus
|
|
11
11
|
end
|
12
12
|
|
13
13
|
if RUBY_ENGINE != 'opal'
|
14
|
+
attr_accessor :operation_timer_tasks
|
15
|
+
|
14
16
|
def valid_operation_class_names
|
15
17
|
@valid_operation_class_names ||= Set.new
|
16
18
|
end
|
@@ -24,6 +26,27 @@ module Isomorfeus
|
|
24
26
|
class_name = class_name.split('>::').last if class_name.start_with?('#<')
|
25
27
|
valid_operation_class_names << class_name
|
26
28
|
end
|
29
|
+
|
30
|
+
def pop_failed_tasks
|
31
|
+
failed_tasks = []
|
32
|
+
[Isomorfeus::Operation::DeferredTask, Isomorfeus::Operation::DailyTask].each do |task_class|
|
33
|
+
task_class.search(:state, 'failed').each do |task|
|
34
|
+
failed_tasks << task
|
35
|
+
task.destroy
|
36
|
+
end
|
37
|
+
end
|
38
|
+
failed_tasks
|
39
|
+
end
|
40
|
+
|
41
|
+
def all_tasks
|
42
|
+
all_tasks = []
|
43
|
+
[Isomorfeus::Operation::DeferredTask, Isomorfeus::Operation::DailyTask].each do |task_class|
|
44
|
+
task_class.search(:state, '*').each do |task|
|
45
|
+
all_tasks << task
|
46
|
+
end
|
47
|
+
end
|
48
|
+
all_tasks
|
49
|
+
end
|
27
50
|
end
|
28
51
|
end
|
29
52
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Operation
|
3
|
+
class DailyTask < LucidObject::Base
|
4
|
+
STATES = %w[ready running failed]
|
5
|
+
# when the task is added to the queue its added as ready
|
6
|
+
# when its running, its running
|
7
|
+
# when it failes, it failed, the exception attribute is filled
|
8
|
+
# when it was successful, its removed from the queue
|
9
|
+
attribute :operation_class_name, class: String, required: true, validate_block: proc { |v| raise 'Invalid Operation class!' unless Isomorfeus.valid_operation_class_name?(v) }
|
10
|
+
attribute :props
|
11
|
+
attribute :user_class_name, class: String, default: 'Anonymous'
|
12
|
+
attribute :user_key, class: String, default: 'anonymous'
|
13
|
+
attribute :state, class: String, required: true, index: :value, ensure: proc { |v| Isomorfeus::Operation::DailyTask::STATES.include?(v) ? v : 'ready' }
|
14
|
+
attribute :exception
|
15
|
+
attribute :rtime
|
16
|
+
attribute :fail, default: true
|
17
|
+
|
18
|
+
def get_exception
|
19
|
+
Marshal.load(exception) if exception
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Operation
|
3
|
+
class DeferredTask < LucidObject::Base
|
4
|
+
STATES = %w[ready running failed]
|
5
|
+
# when the task is added to the queue its added as ready
|
6
|
+
# when its running, its running
|
7
|
+
# when it failes, it failed, the exception attribute is filled
|
8
|
+
# when it was successful, its removed from the queue
|
9
|
+
attribute :operation_class_name, class: String, required: true, validate_block: proc { |v| raise 'Invalid Operation class!' unless Isomorfeus.valid_operation_class_name?(v) }
|
10
|
+
attribute :props
|
11
|
+
attribute :user_class_name, class: String, default: 'Anonymous'
|
12
|
+
attribute :user_key, class: String, default: 'anonymous'
|
13
|
+
attribute :state, class: String, required: true, index: :value, ensure: proc { |v| Isomorfeus::Operation::DeferredTask::STATES.include?(v) ? v : 'ready' }
|
14
|
+
attribute :exception
|
15
|
+
attribute :rtime
|
16
|
+
|
17
|
+
def get_exception
|
18
|
+
Marshal.load(exception) if exception
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Operation
|
3
|
+
module GenericClassApi
|
4
|
+
def current_user
|
5
|
+
Isomorfeus.current_user
|
6
|
+
end
|
7
|
+
|
8
|
+
if RUBY_ENGINE == 'opal'
|
9
|
+
def _process_response(agent)
|
10
|
+
agent.process do |agnt|
|
11
|
+
agnt.response[:result]
|
12
|
+
end
|
13
|
+
if agent.result.key?(:rejected)
|
14
|
+
if agent.result.key?(:error)
|
15
|
+
e = agent.result[:error]
|
16
|
+
exception_class_name = e[:class_name]
|
17
|
+
exception_class = exception_class_name.constantize
|
18
|
+
exception = exception_class.new(e[:message])
|
19
|
+
exception.set_backtrace(e[:backtrace])
|
20
|
+
raise exception
|
21
|
+
else
|
22
|
+
raise agent.result[:rejected]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
agent.result[:resolved]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def promise_run(**props_hash)
|
30
|
+
props = validated_props(props_hash)
|
31
|
+
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, :run, props)
|
32
|
+
.then { |agent| _process_response(agent) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def promise_deferred(**props_hash)
|
36
|
+
props = validated_props(props_hash)
|
37
|
+
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, :deferred, props)
|
38
|
+
.then { |agent| _process_response(agent) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def promise_daily(**props_hash)
|
42
|
+
key = props_hash.delete(:key)
|
43
|
+
props = validated_props(props_hash)
|
44
|
+
props[:key] = key if key
|
45
|
+
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, :daily, props)
|
46
|
+
.then { |agent| _process_response(agent) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def promise_remove_daily(**props_hash)
|
50
|
+
raise "key: must be given" unless props_hash.key?(:key)
|
51
|
+
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, :remove_daily, props_hash)
|
52
|
+
.then { |agent| _process_response(agent) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def promise_daily_exist?(**props_hash)
|
56
|
+
raise "key: must be given" unless props_hash.key?(:key)
|
57
|
+
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, :daily_exist, props_hash)
|
58
|
+
.then { |agent| _process_response(agent) }
|
59
|
+
end
|
60
|
+
else
|
61
|
+
def promise_run(**props_hash)
|
62
|
+
self.new(**props_hash).promise_run
|
63
|
+
end
|
64
|
+
|
65
|
+
def promise_deferred(**props_hash)
|
66
|
+
props = validated_props(props_hash)
|
67
|
+
task = Isomorfeus::Operation::DeferredTask.create(attributes: { operation_class_name: self.name, props: props, user_class_name: current_user.class.name, user_key: current_user.key, state: 'ready' })
|
68
|
+
Promise.new.resolve(task.key)
|
69
|
+
end
|
70
|
+
|
71
|
+
def promise_daily(**props_hash)
|
72
|
+
key = props_hash.delete(:key)
|
73
|
+
props = validated_props(props_hash)
|
74
|
+
task = Isomorfeus::Operation::DailyTask.create(key: key, attributes: { operation_class_name: self.name, props: props, user_class_name: current_user.class.name, user_key: current_user.key, state: 'ready' })
|
75
|
+
Promise.new.resolve(task.key)
|
76
|
+
end
|
77
|
+
|
78
|
+
def promise_remove_daily(**props_hash)
|
79
|
+
raise "key: must be given" unless props_hash.key?(:key)
|
80
|
+
key = props_hash.delete(:key)
|
81
|
+
Isomorfeus::Operation::DailyTask.destroy(key: key)
|
82
|
+
Promise.new.resolve(true)
|
83
|
+
end
|
84
|
+
|
85
|
+
def promise_daily_exist?(**props_hash)
|
86
|
+
raise "key: must be given" unless props_hash.key?(:key)
|
87
|
+
key = props_hash.delete(:key)
|
88
|
+
have_task = !!Isomorfeus::Operation::DailyTask.load(key: key)
|
89
|
+
Promise.new.resolve(have_task)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -10,32 +10,15 @@ module Isomorfeus
|
|
10
10
|
if Isomorfeus.valid_operation_class_name?(operation_class_name)
|
11
11
|
operation_class = Isomorfeus.cached_operation_class(operation_class_name)
|
12
12
|
if operation_class
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if operation_promise.
|
22
|
-
e = operation_promise.error
|
23
|
-
result_hash[:error] = { message: e.message, class_name: e.class.to_s, back_trace: e.backtrace }
|
24
|
-
end
|
25
|
-
response_agent.agent_result = { success: 'ok' , result: result_hash }
|
26
|
-
else
|
27
|
-
start = Time.now
|
28
|
-
timeout = false
|
29
|
-
while !operation_promise.realized?
|
30
|
-
if (Time.now - start) > 20
|
31
|
-
timeout = true
|
32
|
-
break
|
33
|
-
end
|
34
|
-
sleep 0.01
|
35
|
-
end
|
36
|
-
if timeout
|
37
|
-
response_agent.error = { error: 'Timeout' }
|
38
|
-
else
|
13
|
+
response_agent.request[operation_class_name].each_key do |method|
|
14
|
+
props = response_agent.request[operation_class_name][method]
|
15
|
+
props.transform_keys!(&:to_sym)
|
16
|
+
begin
|
17
|
+
case method
|
18
|
+
when 'run'
|
19
|
+
raise 'Access denied!' unless Isomorfeus.current_user.authorized?(operation_class, :promise_run, props)
|
20
|
+
operation_promise = operation_class.promise_run(**props)
|
21
|
+
if operation_promise.realized?
|
39
22
|
state = operation_promise.resolved? ? :resolved : :rejected
|
40
23
|
result_hash = { state => operation_promise.value }
|
41
24
|
if operation_promise.error
|
@@ -43,13 +26,50 @@ module Isomorfeus
|
|
43
26
|
result_hash[:error] = { message: e.message, class_name: e.class.to_s, back_trace: e.backtrace }
|
44
27
|
end
|
45
28
|
response_agent.agent_result = { success: 'ok' , result: result_hash }
|
29
|
+
else
|
30
|
+
start = Time.now
|
31
|
+
timeout = false
|
32
|
+
while !operation_promise.realized?
|
33
|
+
if (Time.now - start) > 20
|
34
|
+
timeout = true
|
35
|
+
break
|
36
|
+
end
|
37
|
+
sleep 0.01
|
38
|
+
end
|
39
|
+
if timeout
|
40
|
+
response_agent.error = { error: 'Timeout' }
|
41
|
+
else
|
42
|
+
state = operation_promise.resolved? ? :resolved : :rejected
|
43
|
+
result_hash = { state => operation_promise.value }
|
44
|
+
if operation_promise.error
|
45
|
+
e = operation_promise.error
|
46
|
+
result_hash[:error] = { message: e.message, class_name: e.class.to_s, back_trace: e.backtrace }
|
47
|
+
end
|
48
|
+
response_agent.agent_result = { success: 'ok' , result: result_hash }
|
49
|
+
end
|
46
50
|
end
|
51
|
+
when 'deferred'
|
52
|
+
raise 'Access denied!' unless Isomorfeus.current_user.authorized?(operation_class, :promise_deferred, props)
|
53
|
+
operation_promise = operation_class.promise_deferred(**props)
|
54
|
+
response_agent.agent_result = { success: 'ok' , result: { :resolved => operation_promise.value }}
|
55
|
+
when 'daily'
|
56
|
+
raise 'Access denied!' unless Isomorfeus.current_user.authorized?(operation_class, :promise_daily, props)
|
57
|
+
operation_promise = operation_class.promise_daily(**props)
|
58
|
+
response_agent.agent_result = { success: 'ok' , result: { :resolved => operation_promise.value }}
|
59
|
+
when 'remove_daily'
|
60
|
+
raise 'Access denied!' unless Isomorfeus.current_user.authorized?(operation_class, :promise_daily, props)
|
61
|
+
operation_promise = operation_class.promise_remove_daily(**props)
|
62
|
+
response_agent.agent_result = { success: 'ok' , result: { :resolved => operation_promise.value }}
|
63
|
+
when 'daily_exist'
|
64
|
+
raise 'Access denied!' unless Isomorfeus.current_user.authorized?(operation_class, :promise_daily, props)
|
65
|
+
operation_promise = operation_class.promise_daily(**props)
|
66
|
+
response_agent.agent_result = { success: 'ok' , result: { :resolved => operation_promise.value }}
|
67
|
+
else
|
68
|
+
response_agent.error = { error: 'No such method!' }
|
47
69
|
end
|
48
|
-
|
49
|
-
response_agent.error = { error:
|
70
|
+
rescue Exception => e
|
71
|
+
response_agent.error = { error: { operation_class_name => "Isomorfeus::Operation::Handler::OperationHandler: #{e.message}" }}
|
50
72
|
end
|
51
|
-
rescue Exception => e
|
52
|
-
response_agent.error = { error: { operation_class_name => "Isomorfeus::Operation::Handler::OperationHandler: #{e.message}" }}
|
53
73
|
end
|
54
74
|
else
|
55
75
|
response_agent.error = { error: { operation_class_name => 'Could not get operation class!' }}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Isomorfeus.operation_timer_tasks = {}
|
2
|
+
|
3
|
+
Isomorfeus.operation_timer_tasks[:deferred] = Concurrent::TimerTask.new(execution_interval: Isomorfeus.production? ? 120 : 10, timeout_interval: 115) do |timer_task|
|
4
|
+
Isomorfeus::Operation::RunTask.new(Isomorfeus::Operation::DeferredTask, timer_task: timer_task, interval: Isomorfeus.production? ? 120 : 10).run
|
5
|
+
end
|
6
|
+
|
7
|
+
Isomorfeus.operation_timer_tasks[:daily] = Concurrent::TimerTask.new(execution_interval: 86400, timeout_interval: 3600) do |timer_task|
|
8
|
+
Isomorfeus::Operation::RunTask.new(Isomorfeus::Operation::DailyTask, timer_task: timer_task, interval: 86400, recurring: true).run
|
9
|
+
end
|
10
|
+
|
11
|
+
Isomorfeus.operation_timer_tasks.each do |k, t|
|
12
|
+
t.execute
|
13
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Operation
|
3
|
+
class RunTask
|
4
|
+
def initialize(task_class, timer_task:, interval:, recurring: false)
|
5
|
+
@task_class = task_class
|
6
|
+
@recurring = recurring
|
7
|
+
@timer_task = timer_task
|
8
|
+
@interval = interval
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
@rtime = Time.now
|
13
|
+
tasks = get_tasks
|
14
|
+
tasks.each do |task|
|
15
|
+
marked = mark_as_running(task)
|
16
|
+
if marked
|
17
|
+
begin
|
18
|
+
operation_class = task.operation_class_name.constantize
|
19
|
+
user_class_name = task.user_class_name
|
20
|
+
Thread.current[:isomorfeus_user] = if user_class_name == 'LocalSystem'
|
21
|
+
LocalSystem.new
|
22
|
+
elsif Isomorfeus.valid_user_class_name?(user_class_name)
|
23
|
+
user_class = user_class_name.constantize
|
24
|
+
user_class.load(key: task.user_key) || Anonymous.new
|
25
|
+
else
|
26
|
+
Anonymous.new
|
27
|
+
end
|
28
|
+
raise 'Access denied!' unless Thread.current[:isomorfeus_user].authorized?(operation_class, :promise_run, task.props)
|
29
|
+
if @recurring
|
30
|
+
operation_class.promise_run(**task.props)
|
31
|
+
.then { mark_as_ready(task) }
|
32
|
+
.fail { |e| task.fail ? mark_as_failed(task, e) : save_exception(task, e) }
|
33
|
+
else
|
34
|
+
operation_class.promise_run(**task.props)
|
35
|
+
.then { remove_task(task) }
|
36
|
+
.fail { |e| mark_as_failed(task, e) }
|
37
|
+
end
|
38
|
+
rescue => e
|
39
|
+
mark_as_failed(task, e)
|
40
|
+
ensure
|
41
|
+
Thread.current[:isomorfeus_user] = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
cleanup
|
46
|
+
@timer_task.execution_interval = @interval - (Time.now - @rtime)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_tasks
|
50
|
+
@task_class.search(:state, 'ready').sort_by! { |task| task.rtime.to_i }
|
51
|
+
end
|
52
|
+
|
53
|
+
def mark_as_running(task)
|
54
|
+
result = false
|
55
|
+
@task_class.object_expander.environment.transaction do
|
56
|
+
task = @task_class.load(key: task.key)
|
57
|
+
if task.rtime.nil? || (task.rtime - @rtime) >= @timer_task.execution_interval
|
58
|
+
if task.state == 'ready'
|
59
|
+
task.state = 'running'
|
60
|
+
task.rtime = @rtime
|
61
|
+
task.save
|
62
|
+
result = true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
result
|
67
|
+
end
|
68
|
+
|
69
|
+
def mark_as_ready(task)
|
70
|
+
task.state = 'ready'
|
71
|
+
task.save
|
72
|
+
end
|
73
|
+
|
74
|
+
def mark_as_failed(task, exception)
|
75
|
+
task.state = 'failed'
|
76
|
+
save_exception(task, exception)
|
77
|
+
end
|
78
|
+
|
79
|
+
def save_exception(taks, exception)
|
80
|
+
task.exception = Marshal.dump(exception)
|
81
|
+
task.save
|
82
|
+
end
|
83
|
+
|
84
|
+
def remove_task(task)
|
85
|
+
@task_class.destroy(key: task.key)
|
86
|
+
end
|
87
|
+
|
88
|
+
def cleanup
|
89
|
+
running_tasks = @task_class.search(:state, 'running').sort_by! { |task| task.rtime.to_i }
|
90
|
+
running_tasks.each do |task|
|
91
|
+
# previous task run has timed out most probably
|
92
|
+
mark_as_failed(task, RuntimeError.new('Operation execution timed out, giving up.')) if (@rtime - task.rtime) > @interval
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/isomorfeus-operation.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
require 'isomorfeus-transport'
|
2
1
|
require 'isomorfeus-policy'
|
2
|
+
require 'isomorfeus-transport'
|
3
|
+
|
3
4
|
require 'isomorfeus/operation/config'
|
5
|
+
require 'isomorfeus/operation/generic_class_api'
|
4
6
|
|
5
7
|
if RUBY_ENGINE == 'opal'
|
6
8
|
Isomorfeus.zeitwerk.push_dir('isomorfeus_operation')
|
@@ -8,22 +10,26 @@ if RUBY_ENGINE == 'opal'
|
|
8
10
|
Isomorfeus.zeitwerk.push_dir('operations')
|
9
11
|
else
|
10
12
|
require 'oj'
|
13
|
+
require 'concurrent/timer_task'
|
14
|
+
require 'isomorfeus-data'
|
11
15
|
require 'isomorfeus/operation/handler/operation_handler'
|
12
16
|
require 'isomorfeus_operation/lucid_operation/gherkin'
|
13
17
|
require 'isomorfeus_operation/lucid_operation/steps'
|
14
18
|
require 'isomorfeus_operation/lucid_operation/promise_run'
|
15
19
|
require 'isomorfeus_operation/lucid_local_operation/mixin'
|
16
20
|
require 'isomorfeus_operation/lucid_local_operation/base'
|
17
|
-
require 'isomorfeus_operation/
|
18
|
-
require 'isomorfeus_operation/
|
21
|
+
require 'isomorfeus_operation/lucid_simple_operation/mixin'
|
22
|
+
require 'isomorfeus_operation/lucid_simple_operation/base'
|
19
23
|
require 'isomorfeus_operation/lucid_operation/mixin'
|
20
24
|
require 'isomorfeus_operation/lucid_operation/base'
|
25
|
+
require 'isomorfeus/operation/deferred_task'
|
26
|
+
require 'isomorfeus/operation/daily_task'
|
27
|
+
require 'isomorfeus/operation/run_task'
|
28
|
+
require 'isomorfeus/operation/init_timer_tasks'
|
21
29
|
|
22
30
|
require 'iso_opal'
|
23
31
|
Opal.append_path(__dir__.untaint) unless IsoOpal.paths.include?(__dir__.untaint)
|
24
32
|
|
25
|
-
# require 'active_support/dependencies'
|
26
|
-
|
27
33
|
path = File.expand_path(File.join('app', 'operations'))
|
28
34
|
|
29
35
|
Isomorfeus.zeitwerk.push_dir(path)
|
@@ -4,72 +4,42 @@ module LucidOperation
|
|
4
4
|
module Mixin
|
5
5
|
def self.included(base)
|
6
6
|
base.extend(LucidPropDeclaration::Mixin)
|
7
|
+
base.extend(LucidOperation::Steps)
|
8
|
+
base.extend(Isomorfeus::Operation::GenericClassApi)
|
7
9
|
|
8
10
|
if RUBY_ENGINE == 'opal'
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def steps
|
14
|
-
end
|
15
|
-
alias :gherkin :steps
|
16
|
-
alias :ensure_steps :steps
|
17
|
-
alias :failure_steps :steps
|
18
|
-
alias :Given :steps
|
19
|
-
alias :And :steps
|
20
|
-
alias :Then :steps
|
21
|
-
alias :When :steps
|
22
|
-
alias :Ensure :steps
|
23
|
-
alias :Failed :steps
|
24
|
-
alias :If_failing :steps
|
25
|
-
alias :When_failing :steps
|
26
|
-
alias :If_this_failed :steps
|
27
|
-
alias :If_that_failed :steps
|
28
|
-
|
29
|
-
def First(regular_expression, &block)
|
30
|
-
Isomorfeus.raise_error(message: "#{self}: First already defined, can only be defined once!") if @first_defined
|
31
|
-
@first_defined = true
|
32
|
-
end
|
11
|
+
def procedure(gherkin_text)
|
12
|
+
end
|
33
13
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
14
|
+
def steps
|
15
|
+
end
|
16
|
+
alias :gherkin :steps
|
17
|
+
alias :ensure_steps :steps
|
18
|
+
alias :failure_steps :steps
|
19
|
+
alias :Given :steps
|
20
|
+
alias :And :steps
|
21
|
+
alias :Then :steps
|
22
|
+
alias :When :steps
|
23
|
+
alias :Ensure :steps
|
24
|
+
alias :Failed :steps
|
25
|
+
alias :If_failing :steps
|
26
|
+
alias :When_failing :steps
|
27
|
+
alias :If_this_failed :steps
|
28
|
+
alias :If_that_failed :steps
|
29
|
+
|
30
|
+
def First(regular_expression, &block)
|
31
|
+
Isomorfeus.raise_error(message: "#{self}: First already defined, can only be defined once!") if @first_defined
|
32
|
+
@first_defined = true
|
33
|
+
end
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
agent.process do |agnt|
|
43
|
-
agnt.response[:result]
|
44
|
-
end
|
45
|
-
if agent.result.key?(:rejected)
|
46
|
-
if agent.result.key?(:error)
|
47
|
-
e = agent.result[:error]
|
48
|
-
exception_class_name = e[:class_name]
|
49
|
-
exception_class = exception_class_name.constantize
|
50
|
-
exception = exception_class.new(e[:message])
|
51
|
-
exception.set_backtrace(e[:backtrace])
|
52
|
-
raise exception
|
53
|
-
else
|
54
|
-
raise agent.result[:rejected]
|
55
|
-
end
|
56
|
-
else
|
57
|
-
agent.result[:resolved]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
35
|
+
def Finally(regular_expression, &block)
|
36
|
+
Isomorfeus.raise_error(message: "#{self}: Finally already defined, can only be defined once!") if @finally_defined
|
37
|
+
@finally_defined = true
|
61
38
|
end
|
62
39
|
else
|
63
40
|
Isomorfeus.add_valid_operation_class(base) unless base == LucidOperation::Base
|
64
|
-
base.extend(LucidOperation::Steps)
|
65
41
|
base.include(LucidOperation::PromiseRun)
|
66
42
|
|
67
|
-
base.instance_exec do
|
68
|
-
def promise_run(**props_hash)
|
69
|
-
self.new(**props_hash).promise_run
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
43
|
attr_reader :props
|
74
44
|
attr_accessor :step_result
|
75
45
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module LucidSimpleOperation
|
2
|
+
module Mixin
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(LucidPropDeclaration::Mixin)
|
5
|
+
base.extend(Isomorfeus::Operation::GenericClassApi)
|
6
|
+
|
7
|
+
if RUBY_ENGINE == 'opal'
|
8
|
+
base.instance_exec do
|
9
|
+
def op
|
10
|
+
end
|
11
|
+
end
|
12
|
+
else
|
13
|
+
Isomorfeus.add_valid_operation_class(base) unless base == LucidSimpleOperation::Base
|
14
|
+
|
15
|
+
base.instance_exec do
|
16
|
+
def op(&block)
|
17
|
+
@op = block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :props
|
24
|
+
|
25
|
+
def initialize(**props_hash)
|
26
|
+
props_hash = self.class.validated_props(props_hash)
|
27
|
+
@props = LucidProps.new(props_hash)
|
28
|
+
end
|
29
|
+
|
30
|
+
def promise_run
|
31
|
+
original_promise = Promise.new
|
32
|
+
|
33
|
+
operation = self
|
34
|
+
promise = original_promise.then do |_|
|
35
|
+
operation.instance_exec(&operation.class.instance_variable_get(:@op))
|
36
|
+
end
|
37
|
+
|
38
|
+
original_promise.resolve
|
39
|
+
promise
|
40
|
+
end
|
41
|
+
|
42
|
+
def current_user
|
43
|
+
Isomorfeus.current_user
|
44
|
+
end
|
45
|
+
|
46
|
+
def pub_sub_client
|
47
|
+
Isomorfeus.pub_sub_client
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isomorfeus-operation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 7.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: concurrent-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.9
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.1.9
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: oj
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,42 +86,56 @@ dependencies:
|
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.14.
|
89
|
+
version: 0.14.21
|
76
90
|
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.14.
|
96
|
+
version: 0.14.21
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: isomorfeus-data
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.3.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.3.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: isomorfeus-policy
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - '='
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
117
|
+
version: 2.3.0
|
90
118
|
type: :runtime
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - '='
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
124
|
+
version: 2.3.0
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: isomorfeus-preact
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
129
|
- - "~>"
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: 10.6.
|
131
|
+
version: 10.6.60
|
104
132
|
type: :runtime
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
136
|
- - "~>"
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: 10.6.
|
138
|
+
version: 10.6.60
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: isomorfeus-redux
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,28 +156,28 @@ dependencies:
|
|
128
156
|
requirements:
|
129
157
|
- - '='
|
130
158
|
- !ruby/object:Gem::Version
|
131
|
-
version: 2.
|
159
|
+
version: 2.3.0
|
132
160
|
type: :runtime
|
133
161
|
prerelease: false
|
134
162
|
version_requirements: !ruby/object:Gem::Requirement
|
135
163
|
requirements:
|
136
164
|
- - '='
|
137
165
|
- !ruby/object:Gem::Version
|
138
|
-
version: 2.
|
166
|
+
version: 2.3.0
|
139
167
|
- !ruby/object:Gem::Dependency
|
140
168
|
name: isomorfeus
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
142
170
|
requirements:
|
143
171
|
- - '='
|
144
172
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
173
|
+
version: 2.3.0
|
146
174
|
type: :development
|
147
175
|
prerelease: false
|
148
176
|
version_requirements: !ruby/object:Gem::Requirement
|
149
177
|
requirements:
|
150
178
|
- - '='
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.
|
180
|
+
version: 2.3.0
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: rake
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,7 +216,12 @@ files:
|
|
188
216
|
- README.md
|
189
217
|
- lib/isomorfeus-operation.rb
|
190
218
|
- lib/isomorfeus/operation/config.rb
|
219
|
+
- lib/isomorfeus/operation/daily_task.rb
|
220
|
+
- lib/isomorfeus/operation/deferred_task.rb
|
221
|
+
- lib/isomorfeus/operation/generic_class_api.rb
|
191
222
|
- lib/isomorfeus/operation/handler/operation_handler.rb
|
223
|
+
- lib/isomorfeus/operation/init_timer_tasks.rb
|
224
|
+
- lib/isomorfeus/operation/run_task.rb
|
192
225
|
- lib/isomorfeus/operation/version.rb
|
193
226
|
- lib/isomorfeus_operation/lucid_local_operation/base.rb
|
194
227
|
- lib/isomorfeus_operation/lucid_local_operation/mixin.rb
|
@@ -197,8 +230,8 @@ files:
|
|
197
230
|
- lib/isomorfeus_operation/lucid_operation/mixin.rb
|
198
231
|
- lib/isomorfeus_operation/lucid_operation/promise_run.rb
|
199
232
|
- lib/isomorfeus_operation/lucid_operation/steps.rb
|
200
|
-
- lib/isomorfeus_operation/
|
201
|
-
- lib/isomorfeus_operation/
|
233
|
+
- lib/isomorfeus_operation/lucid_simple_operation/base.rb
|
234
|
+
- lib/isomorfeus_operation/lucid_simple_operation/mixin.rb
|
202
235
|
homepage: https://isomorfeus.com
|
203
236
|
licenses:
|
204
237
|
- MIT
|
@@ -1,76 +0,0 @@
|
|
1
|
-
module LucidQuickOp
|
2
|
-
module Mixin
|
3
|
-
def self.included(base)
|
4
|
-
base.extend(LucidPropDeclaration::Mixin)
|
5
|
-
|
6
|
-
if RUBY_ENGINE == 'opal'
|
7
|
-
base.instance_exec do
|
8
|
-
def op
|
9
|
-
end
|
10
|
-
|
11
|
-
def promise_run(**props_hash)
|
12
|
-
props = validated_props(props_hash)
|
13
|
-
Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, props).then do |agent|
|
14
|
-
agent.process do
|
15
|
-
agent.response[:result]
|
16
|
-
end
|
17
|
-
if agent.result.key?(:rejected)
|
18
|
-
if agent.result.key?(:error)
|
19
|
-
e = agent.result[:error]
|
20
|
-
exception_class_name = e[:class_name]
|
21
|
-
exception_class = exception_class_name.constantize
|
22
|
-
exception = exception_class.new(e[:message])
|
23
|
-
exception.set_backtrace(e[:backtrace])
|
24
|
-
raise exception
|
25
|
-
else
|
26
|
-
raise agent.result[:rejected]
|
27
|
-
end
|
28
|
-
else
|
29
|
-
agent.result[:resolved]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
else
|
35
|
-
Isomorfeus.add_valid_operation_class(base) unless base == LucidQuickOp::Base
|
36
|
-
|
37
|
-
base.instance_exec do
|
38
|
-
def op(&block)
|
39
|
-
@op = block
|
40
|
-
end
|
41
|
-
|
42
|
-
def promise_run(**props_hash)
|
43
|
-
self.new(**props_hash).promise_run
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
attr_reader :props
|
50
|
-
|
51
|
-
def initialize(**props_hash)
|
52
|
-
props_hash = self.class.validated_props(props_hash)
|
53
|
-
@props = LucidProps.new(props_hash)
|
54
|
-
end
|
55
|
-
|
56
|
-
def promise_run
|
57
|
-
original_promise = Promise.new
|
58
|
-
|
59
|
-
operation = self
|
60
|
-
promise = original_promise.then do |_|
|
61
|
-
operation.instance_exec(&operation.class.instance_variable_get(:@op))
|
62
|
-
end
|
63
|
-
|
64
|
-
original_promise.resolve
|
65
|
-
promise
|
66
|
-
end
|
67
|
-
|
68
|
-
def current_user
|
69
|
-
Isomorfeus.current_user
|
70
|
-
end
|
71
|
-
|
72
|
-
def pub_sub_client
|
73
|
-
Isomorfeus.pub_sub_client
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|