pub_sub_model_sync 0.5.4 → 0.5.7.1
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +33 -3
- data/lib/pub_sub_model_sync/payload.rb +22 -0
- data/lib/pub_sub_model_sync/runner.rb +7 -6
- data/lib/pub_sub_model_sync/service_base.rb +1 -1
- data/lib/pub_sub_model_sync/service_google.rb +3 -1
- data/lib/pub_sub_model_sync/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd5c9fd9bd9c35d62c1eeea4fc91024a5c14f136a757c82bde849501e0445c9d
|
4
|
+
data.tar.gz: 20ea1422d130daa72863743cae0716ba01455e445ee96a9410ec050f0b7f5e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c1c1afba624ef824b269ab7e6aeb112b40bc932b9125ffb90b46b03f7aea96dfc3359fd3ba780b74f9145d37b7fc01be279c8dcf2ecbadce23ac4faad821441
|
7
|
+
data.tar.gz: c908efda5d92bcf8b262586feb22cadc884c24033a43318d22bdd16fb90036d139994fefc02a7b33335dd38f176cb93096e17aca4cd519d4ed8222d911848f69
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
# 0.5.7.1 (January 26, 2021)
|
4
|
+
- fix: does not call :on_error_processing when processing a message
|
5
|
+
|
6
|
+
# 0.5.7 (January 13, 2021)
|
7
|
+
- feat: add method to preload sync listeners
|
8
|
+
|
9
|
+
# 0.5.6 (January 12, 2021)
|
10
|
+
- feat: add payload validation
|
11
|
+
- feat: add method to rebuild payload
|
12
|
+
|
13
|
+
# 0.5.5 (January 11, 2021)
|
14
|
+
- feat: google-pub/sub receive messages in the same order they were delivered
|
15
|
+
|
16
|
+
# 0.5.4.1 (January 8, 2021)
|
17
|
+
- fix: google-pub/sub receive messages sequentially and not in parallel (default 5 threads).
|
18
|
+
|
3
19
|
# 0.5.4 (January 8, 2021)
|
4
20
|
- fix: exclude identifiers when syncing model
|
5
21
|
- feat: callbacks support for future extra params
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -59,10 +59,10 @@ And then execute: $ bundle install
|
|
59
59
|
rake pub_sub_model_sync:start
|
60
60
|
```
|
61
61
|
Note: Publishers do not need todo this
|
62
|
-
Note2 (Rails 6+): Due to Zeitwerk, you need to load listeners manually when syncing
|
62
|
+
Note2 (Rails 6+): Due to Zeitwerk, you need to load listeners manually when syncing without mentioned task (like rails console)
|
63
63
|
```ruby
|
64
64
|
# PubSubModelSync::Config.subscribers ==> []
|
65
|
-
|
65
|
+
PubSubModelSync::Runner.preload_listeners
|
66
66
|
# PubSubModelSync::Config.subscribers ==> [#<PubSubModelSync::Subscriber:0x000.. @klass="Article", @action=:create..., ....]
|
67
67
|
```
|
68
68
|
|
@@ -310,7 +310,37 @@ config.debug = true
|
|
310
310
|
- Add alias attributes when subscribing (similar to publisher)
|
311
311
|
- Add flag ```model.ps_processing``` to indicate that the current transaction is being processed by pub/sub
|
312
312
|
- Auto publish update only if payload has changed
|
313
|
-
- On delete, payload must only be composed by ids
|
313
|
+
- On delete, payload must only be composed by ids
|
314
|
+
- Change notifications into messages
|
315
|
+
|
316
|
+
## Q&A
|
317
|
+
- Error "could not obtain a connection from the pool within 5.000 seconds"
|
318
|
+
This problem occurs because pub/sub dependencies (kafka, google-pubsub, rabbitmq) use many threads to perform notifications where the qty of threads is greater than qty of DB pools ([Google pubsub info](https://github.com/googleapis/google-cloud-ruby/blob/master/google-cloud-pubsub/lib/google/cloud/pubsub/subscription.rb#L888))
|
319
|
+
To fix the problem, edit config/database.yml and increase the quantity of ```pool: 10```
|
320
|
+
- Google pubsub: How to process notifications parallely and not sequentially (default 1 thread)?
|
321
|
+
```ruby PubSubModelSync::ServiceGoogle::LISTEN_SETTINGS = { threads: { callback: qty_threads } } ```
|
322
|
+
Note: by this way some notifications can be processed before others thus missing relationship errors can appear
|
323
|
+
- How to retry failed syncs with sidekiq?
|
324
|
+
```ruby
|
325
|
+
# lib/initializers/pub_sub_config.rb
|
326
|
+
|
327
|
+
class PubSubRecovery
|
328
|
+
include Sidekiq::Worker
|
329
|
+
sidekiq_options queue: :pubsub, retry: 2, backtrace: true
|
330
|
+
|
331
|
+
def perform(payload_data, action)
|
332
|
+
payload = PubSubModelSync::Payload.from_payload_data(payload_data)
|
333
|
+
payload.send(action)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
PubSubModelSync::Config.on_error_publish = lambda do |_e, data|
|
338
|
+
PubSubRecovery.perform_async(data[:payload].to_h, :publish!)
|
339
|
+
end
|
340
|
+
PubSubModelSync::Config.on_error_processing = lambda do |_e, data|
|
341
|
+
PubSubRecovery.perform_async(data[:payload].to_h, :process!)
|
342
|
+
end
|
343
|
+
```
|
314
344
|
|
315
345
|
## Contributing
|
316
346
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module PubSubModelSync
|
4
4
|
class Payload
|
5
|
+
class MissingInfo < StandardError; end
|
5
6
|
attr_reader :data, :attributes, :headers
|
6
7
|
|
7
8
|
# @param data (Hash: { any value }):
|
@@ -11,8 +12,10 @@ module PubSubModelSync
|
|
11
12
|
@attributes = attributes
|
12
13
|
@headers = headers
|
13
14
|
build_headers
|
15
|
+
validate!
|
14
16
|
end
|
15
17
|
|
18
|
+
# @return Hash: payload data
|
16
19
|
def to_h
|
17
20
|
{ data: data, attributes: attributes, headers: headers }
|
18
21
|
end
|
@@ -25,33 +28,52 @@ module PubSubModelSync
|
|
25
28
|
attributes[:action]
|
26
29
|
end
|
27
30
|
|
31
|
+
# Process payload data
|
32
|
+
# (If error will raise exception and wont call on_error_processing callback)
|
28
33
|
def process!
|
29
34
|
process do |publisher|
|
30
35
|
publisher.raise_error = true
|
31
36
|
end
|
32
37
|
end
|
33
38
|
|
39
|
+
# Process payload data
|
40
|
+
# (If error will call on_error_processing callback)
|
34
41
|
def process
|
35
42
|
publisher = PubSubModelSync::MessageProcessor.new(self)
|
36
43
|
yield(publisher) if block_given?
|
37
44
|
publisher.process
|
38
45
|
end
|
39
46
|
|
47
|
+
# Publish payload to pubsub
|
48
|
+
# (If error will raise exception and wont call on_error_publish callback)
|
40
49
|
def publish!
|
41
50
|
klass = PubSubModelSync::MessagePublisher
|
42
51
|
klass.publish(self, raise_error: true)
|
43
52
|
end
|
44
53
|
|
54
|
+
# Publish payload to pubsub
|
55
|
+
# (If error will call on_error_publish callback)
|
45
56
|
def publish
|
46
57
|
klass = PubSubModelSync::MessagePublisher
|
47
58
|
klass.publish(self)
|
48
59
|
end
|
49
60
|
|
61
|
+
# convert payload data into Payload
|
62
|
+
# @param data [Hash]: payload data (:data, :attributes, :headers)
|
63
|
+
def self.from_payload_data(data)
|
64
|
+
data = data.deep_symbolize_keys
|
65
|
+
new(data[:data], data[:attributes], data[:headers])
|
66
|
+
end
|
67
|
+
|
50
68
|
private
|
51
69
|
|
52
70
|
def build_headers
|
53
71
|
headers[:uuid] ||= SecureRandom.uuid
|
54
72
|
headers[:app_key] ||= PubSubModelSync::Config.subscription_key
|
55
73
|
end
|
74
|
+
|
75
|
+
def validate!
|
76
|
+
raise MissingInfo if !attributes[:klass] || !attributes[:action]
|
77
|
+
end
|
56
78
|
end
|
57
79
|
end
|
@@ -4,6 +4,7 @@ require 'active_support/core_ext/module'
|
|
4
4
|
module PubSubModelSync
|
5
5
|
class Runner
|
6
6
|
class ShutDown < StandardError; end
|
7
|
+
delegate :preload_listeners, to: :class
|
7
8
|
attr_accessor :connector
|
8
9
|
|
9
10
|
def initialize
|
@@ -12,12 +13,17 @@ module PubSubModelSync
|
|
12
13
|
|
13
14
|
def run
|
14
15
|
trap_signals!
|
15
|
-
|
16
|
+
preload_listeners
|
16
17
|
start_listeners
|
17
18
|
rescue ShutDown
|
18
19
|
connector.stop
|
19
20
|
end
|
20
21
|
|
22
|
+
def self.preload_listeners
|
23
|
+
Rails.application.try(:eager_load!) if defined?(Rails)
|
24
|
+
Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk::Loader)
|
25
|
+
end
|
26
|
+
|
21
27
|
private
|
22
28
|
|
23
29
|
def start_listeners
|
@@ -31,10 +37,5 @@ module PubSubModelSync
|
|
31
37
|
end
|
32
38
|
%w[INT QUIT TERM].each { |signal| Signal.trap(signal, handler) }
|
33
39
|
end
|
34
|
-
|
35
|
-
def preload_framework!
|
36
|
-
Rails.application.try(:eager_load!) if defined?(Rails)
|
37
|
-
Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk::Loader)
|
38
|
-
end
|
39
40
|
end
|
40
41
|
end
|
@@ -7,6 +7,8 @@ end
|
|
7
7
|
|
8
8
|
module PubSubModelSync
|
9
9
|
class ServiceGoogle < ServiceBase
|
10
|
+
LISTEN_SETTINGS = { threads: { callback: 1 } }.freeze
|
11
|
+
SUBSCRIPTION_SETTINGS = { message_ordering: true }.freeze
|
10
12
|
attr_accessor :service, :topic, :subscription, :subscriber
|
11
13
|
|
12
14
|
def initialize
|
@@ -40,7 +42,7 @@ module PubSubModelSync
|
|
40
42
|
|
41
43
|
def subscribe_to_topic
|
42
44
|
topic.subscription(config.subscription_key) ||
|
43
|
-
topic.subscribe(config.subscription_key)
|
45
|
+
topic.subscribe(config.subscription_key, SUBSCRIPTION_SETTINGS)
|
44
46
|
end
|
45
47
|
|
46
48
|
def process_message(received_message)
|
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: 0.5.
|
4
|
+
version: 0.5.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|