pub_sub_model_sync 1.0.beta → 1.0.beta1

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: 906ba0cfabbe20b6043f277795255a587f4e3f6c535f602ffb6be1dbca6e7d1f
4
- data.tar.gz: 27e291f2bd5054cb1d3b9724d0e3a7e228ff29a833c0905af9ead58b93f84e6c
3
+ metadata.gz: 13b5f627ef31865359d033508451bca2297f99cf2cba31d2d3b1a0edb5e0120e
4
+ data.tar.gz: e273ff16f01bda1cae1ec2d78b8fd33174dadccdc78b4430503bd5ae40a35988
5
5
  SHA512:
6
- metadata.gz: 6982c9ad491fcba5967a42e26e922d9d19aa6e03ca48ea84c174301ca133e5890dffdf6ce138624610c341b7fb26bb2131495f7617b9fbe819ef28e8d10324b3
7
- data.tar.gz: 75274215f707809a35f44d26c31ec6543a8487924c8e28b860dd27422348a5071874dc969c36fb9ce6f5a4d197872e2470b97f5983ae199d900438d2e8602178
6
+ metadata.gz: 8bbff15963073476121be61b70abc9899b34c88f12d4b0c75e658f9554cb97b7a6adfeeff7eb1b265fcdd46d3ab2a9bfe97274fc9cd2d67b3a7192d28cf52fb8
7
+ data.tar.gz: dea3272e6930728975dfa140e5b49355ce799c9361d892f0d2acd5a665a699f16383a930db714f64746f03185726abaa1a477da1ae03a3ca22730e750397dccc
data/.rubocop.yml CHANGED
@@ -7,8 +7,7 @@ AllCops:
7
7
  - 'Gemfile'
8
8
  - 'Rakefile'
9
9
  - 'bin/*'
10
- - 'blog/*'
11
- - 'blog/**/*'
10
+ - 'samples/**/*'
12
11
 
13
12
  Metrics/BlockLength:
14
13
  Exclude:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pub_sub_model_sync (1.0.beta)
4
+ pub_sub_model_sync (1.0.beta1)
5
5
  rails
6
6
 
7
7
  GEM
@@ -115,6 +115,7 @@ GEM
115
115
  gapic-common (~> 0.3)
116
116
  google-cloud-errors (~> 1.0)
117
117
  grpc-google-iam-v1 (>= 0.6.10, < 2.0)
118
+ google-protobuf (3.17.0)
118
119
  google-protobuf (3.17.0-x86_64-linux)
119
120
  googleapis-common-protos (1.3.11)
120
121
  google-protobuf (~> 3.14)
@@ -129,6 +130,9 @@ GEM
129
130
  multi_json (~> 1.11)
130
131
  os (>= 0.9, < 2.0)
131
132
  signet (~> 0.14)
133
+ grpc (1.37.1)
134
+ google-protobuf (~> 3.15)
135
+ googleapis-common-protos-types (~> 1.0)
132
136
  grpc (1.37.1-x86_64-linux)
133
137
  google-protobuf (~> 3.15)
134
138
  googleapis-common-protos-types (~> 1.0)
@@ -152,7 +156,7 @@ GEM
152
156
  multi_json (1.15.0)
153
157
  multipart-post (2.1.1)
154
158
  nio4r (2.5.7)
155
- nokogiri (1.11.3-x86_64-linux)
159
+ nokogiri (1.11.3-x86_64-darwin)
156
160
  racc (~> 1.4)
157
161
  os (1.1.1)
158
162
  parallel (1.20.1)
@@ -244,6 +248,7 @@ GEM
244
248
  zeitwerk (2.4.2)
245
249
 
246
250
  PLATFORMS
251
+ ruby
247
252
  x86_64-linux
248
253
 
249
254
  DEPENDENCIES
data/README.md CHANGED
@@ -364,9 +364,9 @@ Any notification before delivering is transformed as a Payload for a better port
364
364
  **Note**: When any error is raised when saving user or posts, the transaction is cancelled and thus all notifications wont be delivered (customizable by `PubSubModelSync::Config.transactions_use_buffer`).
365
365
 
366
366
  - Manual transactions
367
- `PubSubModelSync::MessagePublisher::transaction(key, use_buffer: , &block)`
367
+ `PubSubModelSync::MessagePublisher::transaction(key, max_buffer: , &block)`
368
368
  - `key` (String|nil) Key used as the ordering key for all inner notifications (When nil, will use `ordering_key` of the first notification)
369
- - `use_buffer:` (Boolean, default: `PubSubModelSync::Config.transactions_use_buffer`)
369
+ - `max_buffer:` (Boolean, default: `PubSubModelSync::Config.transactions_max_buffer`)
370
370
  If true: will save all notifications and deliver all them when transaction has successfully finished. If transaction has failed, then all saved notifications will be discarded (not delivered).
371
371
  If false: will deliver all notifications immediately (no way to rollback notifications if transaction has failed)
372
372
  Sample:
@@ -479,7 +479,9 @@ config.debug = true
479
479
  (Proc) => called after publishing a message
480
480
  - ```.on_error_publish = ->(exception, {payload:}) { payload.delay(...).publish! }```
481
481
  (Proc) => called when failed publishing a message (delayed_job or similar can be used for retrying)
482
- - ```.transactions_use_buffer = true``` (true*|false) Default value for `use_buffer` in transactions.
482
+ - ```.transactions_max_buffer = 100``` (Integer) Once this quantity of notifications is reached, then all notifications will immediately be delivered.
483
+ Note: There is no way to rollback delivered notifications if current transaction fails
484
+ - ```.enable_rails4_before_commit = true``` (true*|false) When false will disable rails 4 hack compatibility and then CRUD notifications will be prepared using `after_commit` callback instead of `before_commit` which will not rollback sql transactions if fails.
483
485
 
484
486
  ## **TODO**
485
487
  - Auto publish update only if payload has changed (see ways to compare previous payload vs new payload)
@@ -8,7 +8,8 @@ module PubSubModelSync
8
8
  # customizable callbacks
9
9
  cattr_accessor(:debug) { false }
10
10
  cattr_accessor :logger # LoggerInst
11
- cattr_accessor(:transactions_use_buffer) { true }
11
+ cattr_accessor(:transactions_max_buffer) { 100 }
12
+ cattr_accessor(:enable_rails4_before_commit) { Rails::VERSION::MAJOR == 4 }
12
13
 
13
14
  cattr_accessor(:on_before_processing) { ->(_payload, _info) {} } # return :cancel to skip
14
15
  cattr_accessor(:on_success_processing) { ->(_payload, _info) {} }
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Rails 4 backward compatibility (Add "simple" ps_before_*_commit callbacks)
4
+ ActiveRecord::ConnectionAdapters::RealTransaction.class_eval do
5
+ alias_method :commit_with_before_commit, :commit
6
+
7
+ def commit
8
+ call_before_commit_records if Rails::VERSION::MAJOR == 4
9
+ commit_with_before_commit
10
+ end
11
+
12
+ private
13
+
14
+ def call_before_commit_records
15
+ ite = records.uniq
16
+ ite.each do |record|
17
+ action = record.previous_changes.include?(:id) ? :create : :update
18
+ action = :destroy if record.destroyed?
19
+ callback_name = "ps_before_#{action}_commit".to_sym
20
+ record.send(callback_name) if record.respond_to?(callback_name)
21
+ end
22
+ end
23
+ end
@@ -22,7 +22,7 @@ module PubSubModelSync
22
22
  def transaction(key, settings = {}, &block)
23
23
  t = init_transaction(key, settings)
24
24
  block.call
25
- t.deliver_all
25
+ t.finish
26
26
  rescue
27
27
  t.rollback
28
28
  raise
@@ -55,14 +55,17 @@ module PubSubModelSync
55
55
 
56
56
  # @param crud_actions (Symbol|Array<Symbol>): :create, :update, :destroy
57
57
  # @param method_name (Symbol, optional) method to be called
58
- def ps_on_crud_event(crud_actions, method_name = nil, &block)
59
- crud_actions = Array(crud_actions)
58
+ def ps_on_crud_event(crud_actions, method_name = nil, &block) # rubocop:disable Metrics/MethodLength
60
59
  callback = ->(action) { method_name ? send(method_name, action) : instance_exec(action, &block) }
61
60
  commit_name = respond_to?(:before_commit) ? :before_commit : :after_commit
62
- crud_actions.each do |action|
63
- send(commit_name, on: :create) { instance_exec(action, &callback) } if action == :create
64
- send(commit_name, on: :update) { instance_exec(action, &callback) } if action == :update
65
- after_destroy { instance_exec(action, &callback) } if action == :destroy
61
+ Array(crud_actions).each do |action|
62
+ if action == :destroy
63
+ after_destroy { instance_exec(action, &callback) }
64
+ elsif PubSubModelSync::Config.enable_rails4_before_commit # rails 4 compatibility
65
+ define_method("ps_before_#{action}_commit") { instance_exec(action, &callback) }
66
+ else
67
+ send(commit_name, on: action) { instance_exec(action, &callback) }
68
+ end
66
69
  end
67
70
  end
68
71
 
@@ -77,7 +80,7 @@ module PubSubModelSync
77
80
  after_create start_transaction, prepend: true # wait for ID
78
81
  before_update start_transaction, prepend: true
79
82
  before_destroy start_transaction, prepend: true
80
- after_commit { @ps_transaction.deliver_all }
83
+ after_commit { @ps_transaction.finish }
81
84
  after_rollback(prepend: true) { @ps_transaction.rollback }
82
85
  end
83
86
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'pub_sub_model_sync'
4
4
  require 'rails'
5
+ require 'pub_sub_model_sync/config'
5
6
  module PubSubModelSync
6
7
  class Railtie < ::Rails::Railtie
7
8
  railtie_name :pub_sub_model_sync
@@ -9,5 +10,9 @@ module PubSubModelSync
9
10
  rake_tasks do
10
11
  load 'pub_sub_model_sync/tasks/worker.rake'
11
12
  end
13
+
14
+ configure do
15
+ require 'pub_sub_model_sync/initializers/before_commit' if PubSubModelSync::Config.enable_rails4_before_commit
16
+ end
12
17
  end
13
18
  end
@@ -3,55 +3,65 @@
3
3
  module PubSubModelSync
4
4
  class Transaction < Base
5
5
  PUBLISHER_KLASS = PubSubModelSync::MessagePublisher
6
- attr_accessor :key, :payloads, :use_buffer, :parent, :children
6
+ attr_accessor :key, :payloads, :max_buffer, :root, :children, :finished
7
7
 
8
8
  # @param key (String|nil) Transaction key, if empty will use the ordering_key from first payload
9
- # @param use_buffer (Boolean, default: true) If false, payloads are delivered immediately
10
- # (no way to cancel/rollback if transaction failed)
11
- def initialize(key, use_buffer: config.transactions_use_buffer)
9
+ # @param max_buffer (Integer) Once this quantity of notifications is reached, then all notifications
10
+ # will immediately be delivered.
11
+ # Note: There is no way to rollback delivered notifications if current transaction fails
12
+ def initialize(key, max_buffer: config.transactions_max_buffer)
12
13
  @key = key
13
- @use_buffer = use_buffer
14
+ @max_buffer = max_buffer
14
15
  @children = []
15
16
  @payloads = []
16
17
  end
17
18
 
18
19
  # @param payload (Payload)
19
20
  def add_payload(payload)
20
- use_buffer ? payloads << payload : deliver_payload(payload)
21
+ payloads << payload
22
+ deliver_payloads if payloads.count >= max_buffer
21
23
  end
22
24
 
23
- def deliver_all
24
- if parent
25
- parent.children = parent.children.reject { |t| t == self }
26
- parent.deliver_all
25
+ def finish # rubocop:disable Metrics/AbcSize
26
+ if root
27
+ root.children = root.children.reject { |t| t == self }
28
+ root.deliver_all if root.finished && root.children.empty?
27
29
  end
28
- payloads.each(&method(:deliver_payload)) if children.empty?
29
- clean_publisher
30
+ self.finished = true
31
+ deliver_all if children.empty?
30
32
  end
31
33
 
32
34
  def add_transaction(transaction)
33
- transaction.parent = self
35
+ transaction.root = self
34
36
  children << transaction
35
37
  transaction
36
38
  end
37
39
 
38
40
  def rollback
39
- log("rollback #{children.count} notifications", :warn) if children.any? && debug?
41
+ log("rollback #{payloads.count} notifications", :warn) if children.any? && debug?
40
42
  self.children = []
41
- parent&.rollback
43
+ root&.rollback
42
44
  clean_publisher
43
45
  end
44
46
 
45
47
  def clean_publisher
46
- PUBLISHER_KLASS.current_transaction = nil if !parent && children.empty?
48
+ PUBLISHER_KLASS.current_transaction = nil if !root && children.empty?
49
+ end
50
+
51
+ def deliver_all
52
+ deliver_payloads
53
+ clean_publisher
47
54
  end
48
55
 
49
56
  private
50
57
 
51
- def deliver_payload(payload)
52
- PUBLISHER_KLASS.connector_publish(payload)
53
- rescue => e
54
- PUBLISHER_KLASS.send(:notify_error, e, payload)
58
+ def deliver_payloads
59
+ payloads.each do |payload|
60
+ PUBLISHER_KLASS.connector_publish(payload)
61
+ rescue => e
62
+ PUBLISHER_KLASS.send(:notify_error, e, payload)
63
+ end
64
+ self.payloads = []
55
65
  end
56
66
  end
57
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PubSubModelSync
4
- VERSION = '1.0.beta'
4
+ VERSION = '1.0.beta1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pub_sub_model_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.beta
4
+ version: 1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Owen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-13 00:00:00.000000000 Z
11
+ date: 2021-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -110,6 +110,7 @@ files:
110
110
  - lib/pub_sub_model_sync/base.rb
111
111
  - lib/pub_sub_model_sync/config.rb
112
112
  - lib/pub_sub_model_sync/connector.rb
113
+ - lib/pub_sub_model_sync/initializers/before_commit.rb
113
114
  - lib/pub_sub_model_sync/message_processor.rb
114
115
  - lib/pub_sub_model_sync/message_publisher.rb
115
116
  - lib/pub_sub_model_sync/mock_google_service.rb