isomorfeus-operation 2.2.10 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7219d159c43e8ff7c984f03884de967389af8d49491b65525c309f01276bca7
4
- data.tar.gz: 07fffbdea0e4bbbadf1027a2781eb9a697c9c53264be251c7be13f30915b6d77
3
+ metadata.gz: b18d527260f0587a538b217ef2bf48de482ab1d5b0ebf4254ab144a30c269994
4
+ data.tar.gz: 296e6ae448f9a1da77ea1a4a69f9cf575a04f350c4eee40ae93b483e252c1e10
5
5
  SHA512:
6
- metadata.gz: 1bb1c92cf61fa2d0a268258f506758d12b0be8b1934e7bdd130b5d83370d188d25cf48be769b53dbf562c91ac6c361db0e6d14d6071eadd9e19659e1e28926f3
7
- data.tar.gz: c3d54ff814a242496a9bf1100b8078460602377f28dd49736876957c97727f792006feda6138d5f576b3f83000e748d112851d97c88840af7f9ce8a2f9ef6735
6
+ metadata.gz: 98b94dbff5c94a2c4f8e108cb9edc6b34f3587247ff728ab92a434d1c5c48e3dd7d51803cdf3f50effcd6c5953e77c6258a90889132ab710d6fe2e15902478d7
7
+ data.tar.gz: 0275e6b05df139a96ea614c9f1b039e828086353c1b4f7f27a9448dcf6bcb4e87e2e313bb6aad90634ae2384cbdc7343aa9b163dd6d473b02991570dfee39335
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.10'
3
+ VERSION = '2.3.1'
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.10
4
+ version: 2.3.1
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-02-26 00:00:00.000000000 Z
11
+ date: 2022-03-12 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.1
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.1
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.10
117
+ version: 2.3.1
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.10
124
+ version: 2.3.1
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.54
131
+ version: 10.6.61
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.54
138
+ version: 10.6.61
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.10
159
+ version: 2.3.1
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.10
166
+ version: 2.3.1
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.10
173
+ version: 2.3.1
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.10
180
+ version: 2.3.1
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