pub_sub_model_sync 1.0.beta → 1.0.beta1

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: 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