railbox 0.1.1 → 0.1.2

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: 8288bdb997d56c541329eed5c0dadda7c6c3b7d14a5796cc146c3ff183b56fda
4
- data.tar.gz: 8c51b795c45826283891f4f6bedb9944064499fdb90eba4d0cfdb26fb135f239
3
+ metadata.gz: 9bee1e734460ab0bc5d07c19cf133c1a46bde8e0e943b7a5e50a480d5fdce24f
4
+ data.tar.gz: 40b7b8f3e1c3ac79447dc56d0eb682ea58a2c82205481f6f13656319a6955803
5
5
  SHA512:
6
- metadata.gz: 77d9775e1701a7c476868e408918a5cf59ecaf2493e2ccbb5c2af1c14b60752e030abb237a1c21b223bca23e83dcc7b7d69cceb6ee2582355c54ab6d1d5301c8
7
- data.tar.gz: dcdc42f6ab3c70380b4835de2218c03b38798ed97ff53eb01d9310468043eb8089024493e3bbfafac84befe06357b1a2ba8101a2ecdac872e5b0207e0c861b12
6
+ metadata.gz: 2c2b6dbde97ef2814a83b5b75149c9e7e0e0f43d1180aff131bf6b37cce3f6be6ded8f4d9257a5792ab93ad528602ec2525802180c75f302710e36fa2ef960c7
7
+ data.tar.gz: e5f8c61ec2fbd84a48301dd84bc608621a10a4ce493cd453c0a90b396dfb37914e81c709543d093ea4792f885f2bc809752869f08ddd2c186800990060e5c0f8
@@ -28,6 +28,14 @@ module Railbox
28
28
  def enqueue(method: 'create', body: {}, **opts)
29
29
  HandlingQueue.enqueue(service: name, method: method, body: body, **opts)
30
30
  end
31
+
32
+ # Base failure hook:
33
+ # - can be safely called even if not overridden in the service;
34
+ # - does nothing by default;
35
+ # - when overridden, has access to `outbox_entity`.
36
+ def on_failure
37
+ # no-op by default
38
+ end
31
39
  end
32
40
  end
33
41
  end
@@ -32,6 +32,12 @@ module Railbox
32
32
  class TransactionalOutbox < ::ActiveRecord::Base
33
33
  belongs_to :relative_entity, polymorphic: true, foreign_key: :entity_id, foreign_type: :entity_type
34
34
 
35
+ enum :status, {in_progress: 'in_progress', failed: 'failed', completed: 'completed'}
36
+
37
+ def action_data
38
+ super&.deep_symbolize_keys || {}
39
+ end
40
+
35
41
  def in_group?
36
42
  group.present? || entity_group.present?
37
43
  end
@@ -10,7 +10,7 @@ module Railbox
10
10
  def update(record, attributes)
11
11
  record.assign_attributes(attributes)
12
12
 
13
- if record.status == 'in_progress'
13
+ if record.in_progress?
14
14
  record.attempts += 1
15
15
 
16
16
  if record.attempts >= Railbox.configuration.max_attempts
@@ -1,17 +1,34 @@
1
1
  module Railbox
2
2
  module Processors
3
3
  class HandlerProcessor
4
+ extend ActiveSupport::Concern
5
+
4
6
  class << self
5
7
 
6
8
  def process(record)
7
- interface = Railbox::TransactionalOutboxInterface.new(record)
8
- action_data = record.action_data.deep_symbolize_keys!
9
- handler = Object.const_get(action_data[:class_name])
10
- handler.outbox_entity = interface
9
+ with_handler(record) do |handler, action_data|
10
+ handler.public_send(action_data[:method_name])
11
+ end
12
+ end
13
+
14
+ def on_failure(record)
15
+ with_handler(record) do |handler, _action_data|
16
+ handler.on_failure
17
+ end
18
+ end
19
+
20
+ private
11
21
 
12
- handler.public_send(action_data[:method_name])
22
+ def with_handler(record)
23
+ interface = Railbox::TransactionalOutboxInterface.new(record)
24
+ action_data = record.action_data
25
+ handler = Object.const_get(action_data[:class_name])
26
+
27
+ handler.outbox_entity = interface
13
28
 
14
- handler.outbox_entity = nil
29
+ yield(handler, action_data)
30
+ ensure
31
+ handler.outbox_entity = nil if handler
15
32
  end
16
33
  end
17
34
  end
@@ -4,7 +4,7 @@ module Railbox
4
4
  class << self
5
5
 
6
6
  def process(record)
7
- action_data = record.action_data.deep_symbolize_keys!
7
+ action_data = record.action_data
8
8
 
9
9
  Railbox::HttpClient::Faraday.request(action_data[:method_name],
10
10
  action_data[:url],
@@ -12,6 +12,9 @@ module Railbox
12
12
  record.body,
13
13
  record.headers)
14
14
  end
15
+
16
+ def on_failure(record)
17
+ end
15
18
  end
16
19
  end
17
20
  end
@@ -12,11 +12,7 @@ module Railbox
12
12
  group.each do |record|
13
13
  process_record(record)
14
14
  rescue => e
15
- TransactionalOutboxMutator.update(record, {failure_reasons: record.failure_reasons << { message: e.message, backtrace: e.backtrace&.take(3), at: DateTime.current}})
16
- raise e if record.in_group? || record.action_type == 'handler'
17
-
18
- Rails.logger.error("RailboxWorker error: #{e.message}\n #{e.backtrace&.take(3)&.join("\n")}")
19
-
15
+ on_failure(e, record)
20
16
  next
21
17
  end
22
18
  rescue => e
@@ -71,23 +67,34 @@ module Railbox
71
67
  all_group_records = scope.order(:created_at).to_a
72
68
 
73
69
  group_records if all_group_records.first&.id.in?(group_records.map(&:id))
74
- end.compact.reject { |_k, v| v.blank? }
70
+ end.compact_blank
75
71
  end
76
72
 
77
73
  def process_record(record)
78
74
  Rails.logger.info("Start process with transactional outbox ID #{record.id}")
79
- processor = PROCESSORS[record.action_type]
80
-
81
- if processor
82
- processor.process(record)
83
- else
84
- raise Railbox::QueueError, "Unknown action_type=#{record.action_type} for outbox #{record.id}"
85
- end
75
+ take_processor(record).process(record)
86
76
 
87
77
  TransactionalOutboxMutator.update(record, {status: 'completed'})
88
78
 
89
79
  Rails.logger.info("Finish process with transactional outbox ID #{record.id}")
90
80
  end
81
+
82
+ def on_failure(error, record)
83
+ record = TransactionalOutboxMutator.update(record, {failure_reasons: record.failure_reasons << {message: error.message, backtrace: error.backtrace&.take(3), at: DateTime.current}})
84
+ take_processor(record).on_failure(record) if record.failed?
85
+
86
+ raise error if record.in_group? || record.action_type == 'handler'
87
+
88
+ Rails.logger.error("RailboxWorker error: #{error.message}\n #{error.backtrace&.take(3)&.join("\n")}")
89
+ end
90
+
91
+ def take_processor(record)
92
+ processor = PROCESSORS[record.action_type]
93
+
94
+ raise Railbox::QueueError, "Unknown action_type=#{record.action_type} for outbox #{record.id}" unless processor
95
+
96
+ processor
97
+ end
91
98
  end
92
99
  end
93
100
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Beresnev