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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42171aa5da25b59d34cc012b7c3ed675aaa9179d224418689087fd28c1a7a62a
4
- data.tar.gz: 257f008c5d0aaffc8fbdc3b157e78c7a47efa87a5ec9a419d8d3bf8ec9c9802e
3
+ metadata.gz: aa334a5da0534716ceda0a03d2661690b5a56afca7e908c099745ce10f30b933
4
+ data.tar.gz: 10ac1f1ea1053ea12e142ea52e5a1908c886d89d20e9c7d6c8ba8891bc1c4291
5
5
  SHA512:
6
- metadata.gz: 1719d39b3d2bdbb60bbb4cd5e46400f15c8159c43ae7f8dc67b062c11eff9f1b412a30ce1071052e4518defac32cb51d1dc59795c07dd0f27a42fe873086e8a7
7
- data.tar.gz: ed8a7f52845444c5a6714314a333128b12e4cf7a502e3638f9f23768af7f150c119ebfcc476a29f059229423971bf83f9a9c82ab8acceba93556bf507c8744b0
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
- - [LucidQuickOp](https://github.com/isomorfeus/isomorfeus-project/blob/master/isomorfeus-operation/docs/quick_op.md) - Quick simple operation, always executed on the server.
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
- props = response_agent.request[operation_class_name]
14
- props.transform_keys!(&:to_sym)
15
- begin
16
- if Isomorfeus.current_user.authorized?(operation_class, :promise_run, props)
17
- operation_promise = operation_class.promise_run(**props)
18
- if operation_promise.realized?
19
- state = operation_promise.resolved? ? :resolved : :rejected
20
- result_hash = { state => operation_promise.value }
21
- if operation_promise.error
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
- else
49
- response_agent.error = { error: 'Access denied!' }
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
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Operation
3
- VERSION = '2.2.11'
3
+ VERSION = '2.3.0'
4
4
  end
5
5
  end
@@ -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/lucid_quick_op/mixin'
18
- require 'isomorfeus_operation/lucid_quick_op/base'
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
- base.instance_exec do
10
- def procedure(gherkin_text)
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
- def Finally(regular_expression, &block)
35
- Isomorfeus.raise_error(message: "#{self}: Finally already defined, can only be defined once!") if @finally_defined
36
- @finally_defined = true
37
- end
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
- def promise_run(**props_hash)
40
- props = validated_props(props_hash)
41
- Isomorfeus::Transport.promise_send_path('Isomorfeus::Operation::Handler::OperationHandler', self.name, props).then do |agent|
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
 
@@ -1,7 +1,7 @@
1
- module LucidQuickOp
1
+ module LucidSimpleOperation
2
2
  class Base
3
3
  def self.inherited(base)
4
- base.include LucidQuickOp::Mixin
4
+ base.include LucidSimpleOperation::Mixin
5
5
  if RUBY_ENGINE != 'opal'
6
6
  Isomorfeus.add_valid_operation_class(base)
7
7
  end
@@ -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.2.11
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-03 00:00:00.000000000 Z
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.17
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.17
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.2.11
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.2.11
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.56
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.56
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.2.11
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.2.11
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.2.11
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.2.11
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/lucid_quick_op/base.rb
201
- - lib/isomorfeus_operation/lucid_quick_op/mixin.rb
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