table_sync 1.8.0 → 1.9.0

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: cfa9b3d17de49a2591644329464d45ba1ddfc6b9a56c76db6eb6c061b439f3e4
4
- data.tar.gz: 7438f913929bd7eb6ae0b6e2d22fcb145b41a62d714aba7e989dcf2868bc7d70
3
+ metadata.gz: '079ab25e5512270ad9c1161f2a0f239fccb7954b5fbe56814605c39a72a87890'
4
+ data.tar.gz: 51b8c5718e91e03aaf7ce45421670999ef83ad7aaefea3961198a09f678149c2
5
5
  SHA512:
6
- metadata.gz: ed0babc48e2b1918ba4ae126215083182c6a3eadec3f79136b68322e2d2563ef02871b82aa86d5f310c77bc8303fc6a38042d35dfba95dab71b7bea653bfb658
7
- data.tar.gz: 11783a0f991fb7d3b39b18e820a82a3075e0f6690ab0bd0d1c5fcb229fa2a0090df673ceacc4e3ec05bc722a42f8657fdd376f18f8f715f27c838efdde5c357b
6
+ metadata.gz: fed258e3f7e24eed98df488c1b5d8ccef4732af5629001695c8053bcd239a46e52b79fef61d9febd627c7c44fe77b7d785f9f4b613aee8492161ec19f2d82288
7
+ data.tar.gz: baf41f7542804dadcdb2c29861bfe82724bdeb743c9b986cec943f0875b97568429c01c6afb4409e49b4f45680a0df5ea951d3bf5c06e874aed6d66a9ed16577
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.9.0] - 2019-07-23
5
+ ### Added
6
+ - add notifications
7
+
4
8
  ## [1.8.0] - 2019-07-23
5
9
  ### Added
6
10
  - `debounce_time` option for publishing
data/docs/synopsis.md CHANGED
@@ -80,6 +80,8 @@ TableSync.routing_metadata_callable = -> (klass, attributes) { attributes.slice(
80
80
  - `TableSync.exchange_name` defines the exchange name used for publishing (optional, falls back
81
81
  to default Rabbit gem configuration).
82
82
 
83
+ - `TableSync.notifier` is a module that provides publish and recieve notifications.
84
+
83
85
  # Manual publishing
84
86
 
85
87
  `TableSync::Publisher.new(object_class, original_attributes, confirm: true, state: :updated, debounce_time: 45)`
@@ -251,5 +253,49 @@ You can set callbacks like this:
251
253
  before_commit on: event, &block
252
254
  after_commit on: event, &block
253
255
  ```
254
- TableSync performs this callbacks after transaction commit as to avoid side effects. Block receives array of
255
- record attributes.
256
+ TableSync performs this callbacks after transaction commit as to avoid side effects. Block receives array of record attributes.
257
+
258
+ ### Notifications
259
+
260
+ #### ActiveSupport adapter
261
+
262
+ You can use an already existing ActiveSupport adapter:
263
+ ```ruby
264
+ TableSync.notifier = TableSync::InstrumentAdapter::ActiveSupport
265
+ ```
266
+
267
+ This instrumentation API is provided by Active Support. It allows to subscribe to notifications:
268
+
269
+ ```ruby
270
+ ActiveSupport::Notifications.subscribe(/tablesync/) do |name, start, finish, id, payload|
271
+ # do something
272
+ end
273
+ ```
274
+
275
+ Types of events available:
276
+ `"tablesync.receive.update"`, `"tablesync.receive.destroy"`, `"tablesync.publish.update"`
277
+ and `"tablesync.publish.destroy"`.
278
+
279
+ You have access to the payload, which contains `event`, `direction`, `table` and `count`.
280
+
281
+ ```
282
+ {
283
+ :event => :update, # one of update / destroy
284
+ :direction => :publish, # one of publish / receive
285
+ :table => "users",
286
+ :count => 1
287
+ }
288
+ ```
289
+
290
+ See more at https://guides.rubyonrails.org/active_support_instrumentation.html
291
+
292
+
293
+ #### Custom adapters
294
+
295
+ You can also create a custom adapter. It is expected to respond to the following method:
296
+
297
+ ```ruby
298
+ def notify(table:, event:, direction:, count:)
299
+ # processes data about table_sync event
300
+ end
301
+ ```
@@ -17,8 +17,10 @@ class TableSync::BatchPublisher < TableSync::BasePublisher
17
17
 
18
18
  def publish_now
19
19
  return unless need_publish?
20
-
21
20
  Rabbit.publish(params)
21
+
22
+ TableSync::Instrument.notify table: TableSync.orm.table_name(object_class), event: event,
23
+ count: publishing_data[:attributes].size, direction: :publish
22
24
  end
23
25
 
24
26
  private
@@ -71,11 +73,15 @@ class TableSync::BatchPublisher < TableSync::BasePublisher
71
73
  def publishing_data
72
74
  {
73
75
  **super,
74
- event: :update,
76
+ event: event,
75
77
  metadata: {},
76
78
  }
77
79
  end
78
80
 
81
+ def event
82
+ :update
83
+ end
84
+
79
85
  def attributes_for_sync
80
86
  return original_attributes_array if push_original_attributes?
81
87
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableSync::Instrument
4
+ module_function
5
+
6
+ def notify(*args)
7
+ TableSync.notifier&.notify(*args)
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableSync::InstrumentAdapter
4
+ module ActiveSupport
5
+ module_function
6
+
7
+ def notify(table:, event:, direction:, count: 1)
8
+ ::ActiveSupport::Notifications.instrument "tablesync.#{direction}.#{event}",
9
+ count: count,
10
+ table: table.to_s,
11
+ event: event,
12
+ direction: direction
13
+ end
14
+ end
15
+ end
@@ -53,7 +53,7 @@ module TableSync::Model
53
53
  def upsert(data:, target_keys:, version_key:, first_sync_time_key:, default_values:)
54
54
  data = Array.wrap(data)
55
55
 
56
- transaction do
56
+ result = transaction do
57
57
  data.map do |datum|
58
58
  conditions = datum.select { |k| target_keys.include?(k) }
59
59
 
@@ -71,13 +71,25 @@ module TableSync::Model
71
71
  row_to_hash(row)
72
72
  end.compact
73
73
  end
74
+
75
+ TableSync::Instrument.notify(
76
+ table: table_name, event: :update, count: result.count, direction: :receive,
77
+ )
78
+
79
+ result
74
80
  end
75
81
 
76
82
  def destroy(data)
77
- transaction do
83
+ result = transaction do
78
84
  row = raw_model.lock("FOR UPDATE").find_by(data)&.destroy!
79
85
  [row_to_hash(row)]
80
86
  end
87
+
88
+ TableSync::Instrument.notify(
89
+ table: table_name, event: :destroy, count: result.count, direction: :receive,
90
+ )
91
+
92
+ result
81
93
  end
82
94
 
83
95
  def transaction(&block)
@@ -99,6 +111,10 @@ module TableSync::Model
99
111
  { schema: schema, name: name }
100
112
  end
101
113
 
114
+ def table_name
115
+ table_info[:name]
116
+ end
117
+
102
118
  def db
103
119
  @raw_model.connection
104
120
  end
@@ -28,17 +28,24 @@ module TableSync::Model
28
28
  insert_data.each { |datum| datum[first_sync_time_key] = Time.current }
29
29
  end
30
30
 
31
- dataset.returning
32
- .insert_conflict(
33
- target: target_keys,
34
- update: upd_spec,
35
- update_where: version_condition,
36
- )
37
- .multi_insert(insert_data)
31
+ result = dataset.returning
32
+ .insert_conflict(
33
+ target: target_keys,
34
+ update: upd_spec,
35
+ update_where: version_condition,
36
+ )
37
+ .multi_insert(insert_data)
38
+
39
+ TableSync::Instrument.notify table: table_name, count: result.count,
40
+ event: :update, direction: :receive
41
+ result
38
42
  end
39
43
 
40
44
  def destroy(data)
41
- dataset.returning.where(data).delete
45
+ result = dataset.returning.where(data).delete
46
+ TableSync::Instrument.notify table: table_name, count: result.count,
47
+ event: :destroy, direction: :receive
48
+ result
42
49
  end
43
50
 
44
51
  def transaction(&block)
@@ -16,6 +16,10 @@ module TableSync::ORMAdapter
16
16
  object.attributes
17
17
  end
18
18
 
19
+ def table_name(object)
20
+ object.table_name
21
+ end
22
+
19
23
  def setup_sync(klass, **opts)
20
24
  debounce_time = opts.delete(:debounce_time)
21
25
 
@@ -16,6 +16,10 @@ module TableSync::ORMAdapter
16
16
  object.values
17
17
  end
18
18
 
19
+ def table_name(object)
20
+ object.table_name
21
+ end
22
+
19
23
  def setup_sync(klass, **opts)
20
24
  if_predicate = to_predicate(opts.delete(:if), true)
21
25
  unless_predicate = to_predicate(opts.delete(:unless), false)
@@ -34,6 +34,8 @@ class TableSync::Publisher < TableSync::BasePublisher
34
34
  return if !object && !destroyed?
35
35
 
36
36
  Rabbit.publish(params)
37
+ TableSync::Instrument.notify table: TableSync.orm.table_name(object_class),
38
+ event: event, direction: :publish
37
39
  end
38
40
 
39
41
  private
@@ -77,7 +79,7 @@ class TableSync::Publisher < TableSync::BasePublisher
77
79
  def publishing_data
78
80
  {
79
81
  **super,
80
- event: (destroyed? ? :destroy : :update),
82
+ event: event,
81
83
  metadata: { created: created? },
82
84
  }
83
85
  end
@@ -100,6 +102,10 @@ class TableSync::Publisher < TableSync::BasePublisher
100
102
  TableSync.orm.find(object_class, needle)
101
103
  end
102
104
 
105
+ def event
106
+ destroyed? ? :destroy : :update
107
+ end
108
+
103
109
  def needle
104
110
  original_attributes.slice(*primary_keys)
105
111
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableSync
4
- VERSION = "1.8.0"
4
+ VERSION = "1.9.0"
5
5
  end
data/lib/table_sync.rb CHANGED
@@ -22,6 +22,8 @@ module TableSync
22
22
  require_relative "./table_sync/orm_adapter/sequel"
23
23
  require_relative "./table_sync/model/active_record"
24
24
  require_relative "./table_sync/model/sequel"
25
+ require_relative "./table_sync/instrument"
26
+ require_relative "./table_sync/instrument_adapter/active_support"
25
27
 
26
28
  class << self
27
29
  include Memery
@@ -31,6 +33,7 @@ module TableSync
31
33
  attr_accessor :routing_key_callable
32
34
  attr_accessor :exchange_name
33
35
  attr_accessor :routing_metadata_callable
36
+ attr_accessor :notifier
34
37
 
35
38
  def sync(*args)
36
39
  orm.setup_sync(*args)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: table_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Umbrellio
@@ -263,6 +263,8 @@ files:
263
263
  - lib/table_sync/dsl.rb
264
264
  - lib/table_sync/errors.rb
265
265
  - lib/table_sync/event_actions.rb
266
+ - lib/table_sync/instrument.rb
267
+ - lib/table_sync/instrument_adapter/active_support.rb
266
268
  - lib/table_sync/model/active_record.rb
267
269
  - lib/table_sync/model/sequel.rb
268
270
  - lib/table_sync/orm_adapter/active_record.rb