table_sync 1.8.0 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/docs/synopsis.md +48 -2
- data/lib/table_sync/batch_publisher.rb +8 -2
- data/lib/table_sync/instrument.rb +9 -0
- data/lib/table_sync/instrument_adapter/active_support.rb +15 -0
- data/lib/table_sync/model/active_record.rb +18 -2
- data/lib/table_sync/model/sequel.rb +15 -8
- data/lib/table_sync/orm_adapter/active_record.rb +4 -0
- data/lib/table_sync/orm_adapter/sequel.rb +4 -0
- data/lib/table_sync/publisher.rb +7 -1
- data/lib/table_sync/version.rb +1 -1
- data/lib/table_sync.rb +3 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '079ab25e5512270ad9c1161f2a0f239fccb7954b5fbe56814605c39a72a87890'
|
4
|
+
data.tar.gz: 51b8c5718e91e03aaf7ce45421670999ef83ad7aaefea3961198a09f678149c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fed258e3f7e24eed98df488c1b5d8ccef4732af5629001695c8053bcd239a46e52b79fef61d9febd627c7c44fe77b7d785f9f4b613aee8492161ec19f2d82288
|
7
|
+
data.tar.gz: baf41f7542804dadcdb2c29861bfe82724bdeb743c9b986cec943f0875b97568429c01c6afb4409e49b4f45680a0df5ea951d3bf5c06e874aed6d66a9ed16577
|
data/CHANGELOG.md
CHANGED
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
|
-
|
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:
|
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,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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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.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)
|
data/lib/table_sync/publisher.rb
CHANGED
@@ -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:
|
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
|
data/lib/table_sync/version.rb
CHANGED
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.
|
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
|