table_sync 5.1.0 → 6.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 +42 -0
- data/Gemfile.lock +3 -3
- data/README.md +3 -0
- data/docs/publishing/configuration.md +143 -0
- data/docs/publishing/manual.md +155 -0
- data/docs/publishing/publishers.md +162 -0
- data/docs/publishing.md +35 -105
- data/lib/table_sync/errors.rb +31 -22
- data/lib/table_sync/event.rb +35 -0
- data/lib/table_sync/orm_adapter/active_record.rb +25 -0
- data/lib/table_sync/orm_adapter/base.rb +92 -0
- data/lib/table_sync/orm_adapter/sequel.rb +29 -0
- data/lib/table_sync/publishing/batch.rb +53 -0
- data/lib/table_sync/publishing/data/objects.rb +50 -0
- data/lib/table_sync/publishing/data/raw.rb +27 -0
- data/lib/table_sync/publishing/helpers/attributes.rb +63 -0
- data/lib/table_sync/publishing/helpers/debounce.rb +134 -0
- data/lib/table_sync/publishing/helpers/objects.rb +39 -0
- data/lib/table_sync/publishing/message/base.rb +73 -0
- data/lib/table_sync/publishing/message/batch.rb +14 -0
- data/lib/table_sync/publishing/message/raw.rb +54 -0
- data/lib/table_sync/publishing/message/single.rb +13 -0
- data/lib/table_sync/publishing/params/base.rb +66 -0
- data/lib/table_sync/publishing/params/batch.rb +23 -0
- data/lib/table_sync/publishing/params/raw.rb +7 -0
- data/lib/table_sync/publishing/params/single.rb +31 -0
- data/lib/table_sync/publishing/raw.rb +21 -0
- data/lib/table_sync/publishing/single.rb +65 -0
- data/lib/table_sync/publishing.rb +20 -5
- data/lib/table_sync/receiving/config.rb +6 -4
- data/lib/table_sync/receiving/handler.rb +10 -6
- data/lib/table_sync/receiving.rb +0 -2
- data/lib/table_sync/setup/active_record.rb +22 -0
- data/lib/table_sync/setup/base.rb +67 -0
- data/lib/table_sync/setup/sequel.rb +26 -0
- data/lib/table_sync/version.rb +1 -1
- data/lib/table_sync.rb +31 -8
- metadata +28 -7
- data/lib/table_sync/publishing/base_publisher.rb +0 -110
- data/lib/table_sync/publishing/batch_publisher.rb +0 -109
- data/lib/table_sync/publishing/orm_adapter/active_record.rb +0 -32
- data/lib/table_sync/publishing/orm_adapter/sequel.rb +0 -57
- data/lib/table_sync/publishing/publisher.rb +0 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7854c781cde972c7dc2d12266f5c9f302e4a9a6b2ae4cfea8215c13bfb9dc326
|
4
|
+
data.tar.gz: dd87d2bc24ec62be162375352cd4f18fa1e0363f80cae49295dc2448d6c97aba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53d28d64907a36913b49a274246b096880be2be13767d639c9ed3e3e7951ba9595c1e548db4b09223ad41c0f36ef536b6ab13fd961ef2b11e2be1b769b12ce05
|
7
|
+
data.tar.gz: cc562e11bfdb74e3049857c96d428222d2c039ebf3808651f741ce20bdc969f57aca8a883ee568e33d06206303b5b4f54b8d6e4ca91e285c0ff63388653dfb3f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,48 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [6.0.0] - 2021-10-15
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- A lot of specs for all the refactoring.
|
8
|
+
- Docs
|
9
|
+
- 100% coverage
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
- Heavy refactoring of Publisher and BatchPublisher.
|
13
|
+
All code is separated in different modules and classes.
|
14
|
+
|
15
|
+
1. Job callables are now called:
|
16
|
+
- single_publishing_job_class_callable
|
17
|
+
- batch_publishing_job_class_callable
|
18
|
+
|
19
|
+
2. Now there are three main classes for messaging:
|
20
|
+
- TableSync::Publishing::Single - sends one row with initialization
|
21
|
+
- TableSync::Publishing::Batch - sends batch of rows with initialization
|
22
|
+
- TableSync::Publishing::Raw - sends raw data without checks
|
23
|
+
|
24
|
+
Separate classes for publishing, object data, Rabbit params, debounce, serialization.
|
25
|
+
|
26
|
+
3. Jobs are not constrained by being ActiveJob anymore. Just need to have #perform_at method
|
27
|
+
|
28
|
+
4. Changed some method names towards consistency:
|
29
|
+
- attrs_for_routing_key -> attributes_for_routing_key
|
30
|
+
- attrs_for_metadata -> attributes_for_headers
|
31
|
+
|
32
|
+
5. Moved TableSync setup into separate classes.
|
33
|
+
|
34
|
+
6. Changed ORMAdapters.
|
35
|
+
|
36
|
+
7. Destroyed objects are initialized.
|
37
|
+
Now custom attributes for destruction will be called on instances.
|
38
|
+
- Obj.table_sync_destroy_attributes() -> Obj#attributes_for_destroy
|
39
|
+
|
40
|
+
8. Event constants are now kept in one place.
|
41
|
+
|
42
|
+
### Removed
|
43
|
+
|
44
|
+
- Plugin Errors
|
45
|
+
|
4
46
|
## [5.1.0] - 2021-09-09
|
5
47
|
|
6
48
|
### Changed
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
table_sync (
|
4
|
+
table_sync (6.0)
|
5
5
|
memery
|
6
6
|
rabbit_messaging
|
7
7
|
rails
|
@@ -98,7 +98,7 @@ GEM
|
|
98
98
|
nokogiri (>= 1.5.9)
|
99
99
|
mail (2.7.1)
|
100
100
|
mini_mime (>= 0.1.1)
|
101
|
-
marcel (1.0.
|
101
|
+
marcel (1.0.2)
|
102
102
|
memery (1.4.1)
|
103
103
|
ruby2_keywords (~> 0.0.2)
|
104
104
|
method_source (1.0.0)
|
@@ -106,7 +106,7 @@ GEM
|
|
106
106
|
mini_portile2 (2.6.1)
|
107
107
|
minitest (5.14.4)
|
108
108
|
nio4r (2.5.8)
|
109
|
-
nokogiri (1.12.
|
109
|
+
nokogiri (1.12.5)
|
110
110
|
mini_portile2 (~> 2.6.1)
|
111
111
|
racc (~> 1.4)
|
112
112
|
parallel (1.20.1)
|
data/README.md
CHANGED
@@ -22,6 +22,9 @@ require 'table_sync'
|
|
22
22
|
|
23
23
|
- [Message protocol](docs/message_protocol.md)
|
24
24
|
- [Publishing](docs/publishing.md)
|
25
|
+
- [Publishers](docs/publishing/publishers.md)
|
26
|
+
- [Configuration](docs/publishing/configuration.md)
|
27
|
+
- [Manual Sync (examples)](docs/publishing/manual.md)
|
25
28
|
- [Receiving](docs/receiving.md)
|
26
29
|
- [Notifications](docs/notifications.md)
|
27
30
|
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Configuration
|
2
|
+
|
3
|
+
Customization, configuration and other options.
|
4
|
+
|
5
|
+
## Model Customization
|
6
|
+
|
7
|
+
There are methods you can define on a synched model to customize published messages for it.
|
8
|
+
|
9
|
+
### `#attributes_for_sync`
|
10
|
+
|
11
|
+
Models can implement `#attributes_for_sync` to override which attributes are published for `update` and `create` events. If not present, all attributes are published.
|
12
|
+
|
13
|
+
### `#attributes_for_destroy`
|
14
|
+
|
15
|
+
Models can implement `#attributes_for_destroy` to override which attributes are published for `destroy` events. If not present, `needle` (primary key) is published.
|
16
|
+
|
17
|
+
### `#attributes_for_routing_key`
|
18
|
+
|
19
|
+
Models can implement `#attributes_for_routing_key` to override which attributes are given to the `routing_key_callable`. If not present, published attributes are given.
|
20
|
+
|
21
|
+
### `#attributes_for_headers`
|
22
|
+
|
23
|
+
Models can implement `#attributes_for_headers` to override which attributes are given to the `headers_callable`. If not present, published attributes are given.
|
24
|
+
|
25
|
+
### `.table_sync_model_name`
|
26
|
+
|
27
|
+
Models can implement `.table_sync_model_name` class method to override the model name used for publishing events. Default is a model class name.
|
28
|
+
|
29
|
+
## Callables
|
30
|
+
|
31
|
+
Callables are defined once. TableSync will use them to dynamically resolve things like jobs, routing_key and headers.
|
32
|
+
|
33
|
+
### Single publishing job (required for automatic and delayed publishing)
|
34
|
+
|
35
|
+
- `TableSync.single_publishing_job_class_callable` is a callable which should resolve to a class that calls TableSync back to actually publish changes.
|
36
|
+
|
37
|
+
It is expected to have `.perform_at(hash_with_options)` and it will be passed a hash with the following keys:
|
38
|
+
|
39
|
+
- `original_attributes` - serialized `original_attributes`
|
40
|
+
- `object_class` - model name
|
41
|
+
- `debounce_time` - pause between publishing messages
|
42
|
+
- `event` - type of event that happened to synched entity
|
43
|
+
- `perform_at` - time to perform the job at (depends on debounce)
|
44
|
+
|
45
|
+
Example:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
TableSync.single_publishing_job_class_callable = -> { TableSync::Job }
|
49
|
+
|
50
|
+
class TableSync::Job < ActiveJob::Base
|
51
|
+
def perform(jsoned_attributes)
|
52
|
+
TableSync::Publishing::Single.new(
|
53
|
+
JSON.parse(jsoned_attributes),
|
54
|
+
).publish_now
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.perform_at(attributes)
|
58
|
+
set(wait_until: attributes.delete(:perform_at))
|
59
|
+
.perform_later(attributes.to_json)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# will enqueue the job described above
|
64
|
+
|
65
|
+
TableSync::Publishing::Single.new(
|
66
|
+
object_class: "User",
|
67
|
+
original_attributes: { id: 1, name: "Mark" }, # will be serialized!
|
68
|
+
debounce_time: 60,
|
69
|
+
event: :update,
|
70
|
+
).publish_later
|
71
|
+
```
|
72
|
+
|
73
|
+
### Batch publishing job (required only for `TableSync::Publishing::Batch#publish_later`)
|
74
|
+
|
75
|
+
- `TableSync.batch_publishing_job_class_callable` is a callable which should resolve to a class that calls TableSync back to actually publish changes.
|
76
|
+
|
77
|
+
It is expected to have `.perform_later(hash_with_options)` and it will be passed a hash with the following keys:
|
78
|
+
|
79
|
+
- `original_attributes` - array of serialized `original_attributes`
|
80
|
+
- `object_class` - model name
|
81
|
+
- `event` - type of event that happened to synched entity
|
82
|
+
- `routing_key` - custom routing_key (optional)
|
83
|
+
- `headers` - custom headers (optional)
|
84
|
+
|
85
|
+
More often than not this job is not very useful, since it makes more sense to use `#publish_now` from an already existing job that does a lot of things (not just publishing messages).
|
86
|
+
|
87
|
+
### Example
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
TableSync.batch_publishing_job_class_callable = -> { TableSync::BatchJob }
|
91
|
+
|
92
|
+
class TableSync::BatchJob < ActiveJob::Base
|
93
|
+
def perform(jsoned_attributes)
|
94
|
+
TableSync::Publishing::Batch.new(
|
95
|
+
JSON.parse(jsoned_attributes),
|
96
|
+
).publish_now
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.perform_later(attributes)
|
100
|
+
super(attributes.to_json)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
TableSync::Publishing::Batch.new(
|
105
|
+
object_class: "User",
|
106
|
+
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }], # will be serialized!
|
107
|
+
event: :create,
|
108
|
+
routing_key: :custom_key, # optional
|
109
|
+
headers: { type: "admin" }, # optional
|
110
|
+
).publish_later
|
111
|
+
```
|
112
|
+
|
113
|
+
### Routing key callable (required)
|
114
|
+
|
115
|
+
- `TableSync.routing_key_callable` is a callable that resolves which routing key to use when publishing changes. It receives object class and published attributes or `#attributes_for_routing_key` (if defined).
|
116
|
+
|
117
|
+
Example:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
TableSync.routing_key_callable = -> (klass, attributes) { klass.gsub('::', '_').tableize }
|
121
|
+
```
|
122
|
+
|
123
|
+
### Headers callable (required)
|
124
|
+
|
125
|
+
- `TableSync.headers_callable` is a callable that adds RabbitMQ headers which can be used in routing. It receives object class and published attributes or `#attributes_for_headers` (if defined).
|
126
|
+
|
127
|
+
One possible way of using it is defining a headers exchange and routing rules based on key-value pairs (which correspond to sent headers).
|
128
|
+
|
129
|
+
Example:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
TableSync.routing_metadata_callable = -> (klass, attributes) { attributes.slice("project_id") }
|
133
|
+
```
|
134
|
+
|
135
|
+
## Other
|
136
|
+
|
137
|
+
- `TableSync.exchange_name` defines the exchange name used for publishing (optional, falls back to default Rabbit gem configuration).
|
138
|
+
|
139
|
+
- `TableSync.notifier` is a module that provides publish and recieve notifications.
|
140
|
+
|
141
|
+
- `TableSync.raise_on_empty_message` - raises an error on empty message if set to true.
|
142
|
+
|
143
|
+
- `TableSync.orm` - set ORM (ActiveRecord or Sequel) used to process given entities. Required!
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# Manual Sync
|
2
|
+
|
3
|
+
There are two ways you can manually publish large amounts of data.
|
4
|
+
|
5
|
+
### `TableSync::Publishing:Batch`
|
6
|
+
|
7
|
+
Easier to use, but does a lot of DB queries. May filter out invalid PK values.
|
8
|
+
|
9
|
+
#### Pros:
|
10
|
+
|
11
|
+
- requires less work
|
12
|
+
- it will automatically use methods for data customization (`#attributes_for_sync`, `#attributes_for_destroy`)
|
13
|
+
- you can be sure that data you publish is valid (more or less)
|
14
|
+
- serializes values for (`#publish_later`)
|
15
|
+
|
16
|
+
#### Cons:
|
17
|
+
|
18
|
+
- it queries database for each entity in batch (for `create` and `update`)
|
19
|
+
- it may also do a lot of queries if `#attributes_for_sync` contains additional data from other connected entities
|
20
|
+
- serializes values for (`#publish_later`); if your PK contains invalid values (ex. Date) they will be filtered out
|
21
|
+
|
22
|
+
### `TableSync::Publishing:Raw`
|
23
|
+
|
24
|
+
More complex to use, but requires very few DB queries.
|
25
|
+
You are responsible for the data you send!
|
26
|
+
|
27
|
+
#### Pros:
|
28
|
+
|
29
|
+
- very customizable; only requirement - `object_class` must exist
|
30
|
+
- you can send whatever data you want
|
31
|
+
|
32
|
+
#### Cons:
|
33
|
+
|
34
|
+
- you have to manually prepare data for publishing
|
35
|
+
- you have to be really sure you are sending valid data
|
36
|
+
|
37
|
+
## Tips
|
38
|
+
|
39
|
+
- **Don't make data batches too large!**
|
40
|
+
|
41
|
+
It may result in failure to process them. Good rule is to send approx. 5000 rows in one batch.
|
42
|
+
|
43
|
+
- **Make pauses between publishing data batches!**
|
44
|
+
|
45
|
+
Publishing without pause may overwhelm the receiving side. Either their background job processor (ex. Sidekiq) may clog with jobs, or their consumers may not be able to get messages from Rabbit server fast enough.
|
46
|
+
|
47
|
+
1 or 2 seconds is a good wait period.
|
48
|
+
|
49
|
+
- **Do not use `TableSync::Publishing:Single` to send millions or even thousands of rows of data.**
|
50
|
+
|
51
|
+
Or just calling update on rows with automatic sync.
|
52
|
+
It WILL overwhelm the receiving side. Especially if they have some additional receiving logic.
|
53
|
+
|
54
|
+
- **On the receiving side don't create job with custom logic (if it exists) for every row in a batch.**
|
55
|
+
|
56
|
+
Better to process it whole. Otherwise three batches of 5000 will result in 15000 new jobs.
|
57
|
+
|
58
|
+
- **Send one test batch before publishing the rest of the data.**
|
59
|
+
|
60
|
+
Make sure it was received properly. This way you won't send a lot invalid messages.
|
61
|
+
|
62
|
+
- **Check the other arguments.**
|
63
|
+
|
64
|
+
- Ensure the routing_key is correct if you are using a custom one. Remember, that batch publishing ignores `#attributes_for_routing_key` on a model.
|
65
|
+
- Ensure that `object_class` is correct. And it belongs to entities you want to send.
|
66
|
+
- Ensure that you chose the correct event.
|
67
|
+
- If you have some logic depending on headers, ensure they are also correct. Remember, that batch publishing ignores `#attributes_for_headers` on a model.
|
68
|
+
|
69
|
+
- **You can check what you send before publishing with:**
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
TableSync::Publishing:Batch.new(...).message.message_params
|
73
|
+
|
74
|
+
TableSync::Publishing:Raw.new(...).message.message_params
|
75
|
+
```
|
76
|
+
|
77
|
+
## Examples
|
78
|
+
|
79
|
+
### `TableSync::Publishing:Raw`
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# For Sequel
|
83
|
+
# gem 'sequel-batches' or equivalent that will allow you to chunk data somehow
|
84
|
+
# or #each_page from Sequel
|
85
|
+
|
86
|
+
# this is a simple query
|
87
|
+
# they can be much more complex, with joins and other things
|
88
|
+
# just make sure that it results in a set of data you expect
|
89
|
+
data = User.in_batches(of: 5000).naked.select(:id, :name, :email)
|
90
|
+
|
91
|
+
data.each_with_index do |batch, i|
|
92
|
+
TableSync::Publishing::Raw.new(
|
93
|
+
object_class: "User",
|
94
|
+
original_attributes: batch,
|
95
|
+
event: :create,
|
96
|
+
routing_key: :custom_key, # optional
|
97
|
+
headers: { type: "admin" }, # optional
|
98
|
+
).publish_now
|
99
|
+
|
100
|
+
# make a pause between batches
|
101
|
+
sleep 1
|
102
|
+
|
103
|
+
# for when you are sending from terminal
|
104
|
+
# allows you to keep an eye on progress
|
105
|
+
# you can create more complex output
|
106
|
+
puts "Batch #{i} sent!"
|
107
|
+
end
|
108
|
+
|
109
|
+
```
|
110
|
+
|
111
|
+
#### Another way to gather data
|
112
|
+
|
113
|
+
If you don't want to create a data query (maybe it's too complex) but there is a lot of quereing in `#attributes_for_sync` and you are willing to trade a little bit of perfomance, you can try the following.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
class User < Sequel
|
117
|
+
one_to_many :user_info
|
118
|
+
|
119
|
+
# For example our receiving side wants to know the ips user logged in under
|
120
|
+
# But doesn't want to sync the user_info
|
121
|
+
def attributes_for_sync
|
122
|
+
attributes.merge(
|
123
|
+
ips: user_info.ips
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# to prevent the need to query for every piece of additional data we can user eager load
|
129
|
+
# and construct published data by calling #attributes_for_sync
|
130
|
+
# don't forget to chunk it into more managable sizes before trying to send
|
131
|
+
data = User.eager(:statuses).map { |user| user.attributes_for_sync }
|
132
|
+
```
|
133
|
+
This way it will not make unnecessary queries.
|
134
|
+
|
135
|
+
### `TableSync::Publishing::Batch`
|
136
|
+
|
137
|
+
Remember, it will query or initialize each row.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
# You can just send ids.
|
141
|
+
data = User.in_batches(of: 5000).naked.select(:id)
|
142
|
+
|
143
|
+
data.each_with_index do |data, i|
|
144
|
+
TableSync::Publishing::Batch.new(
|
145
|
+
object_class: "User",
|
146
|
+
original_attributes: data,
|
147
|
+
event: :create,
|
148
|
+
routing_key: :custom_key, # optional
|
149
|
+
headers: { type: "admin" }, # optional
|
150
|
+
).publish_now
|
151
|
+
|
152
|
+
sleep 1
|
153
|
+
puts "Batch #{i} sent!"
|
154
|
+
end
|
155
|
+
```
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# Publishers
|
2
|
+
|
3
|
+
There are three publishers you can use to send data.
|
4
|
+
|
5
|
+
- `TableSync::Publishing::Single` - sends one row with initialization.
|
6
|
+
- `TableSync::Publishing::Batch` - sends a batch of rows with initialization.
|
7
|
+
- `TableSync::Publishing::Raw` - sends raw data without checks.
|
8
|
+
|
9
|
+
## Single
|
10
|
+
|
11
|
+
`TableSync::Publishing::Single` - sends one row with initialization.
|
12
|
+
|
13
|
+
This is a publisher called by `TableSync.sync(self)`.
|
14
|
+
|
15
|
+
### Expected parameters:
|
16
|
+
|
17
|
+
- `object_class` - class (model) used to initialize published object
|
18
|
+
- `original_attributes` - attributes used to initialize `object_class` with
|
19
|
+
- `debounce_time` - minimum allowed time between delayed publishings
|
20
|
+
- `event` - type of event that happened to the published object (`create`, `update`, `destroy`); `update` by default
|
21
|
+
|
22
|
+
### What it does (when uses `#publish_now`):
|
23
|
+
- takes in the `original_attributes`, `object_class`, `event`
|
24
|
+
- constantizes `object_class`
|
25
|
+
- extracts the primary key (`needle`) of the `object_class` from the `original_attributes`
|
26
|
+
- queries the database for the object with the `needle` (for `update` and `create`) or initializes the `object_class` with `original_attributes` (for `destroy`)
|
27
|
+
- constructs routing_key using `routing_key_callable` and `#attributes_for_routing_key` (if defined)
|
28
|
+
- constructs headers using `headers_callable` and `#attributes_for_headers` (if defined)
|
29
|
+
- publishes Rabbit message (uses attributes from queried/initialized object as data)
|
30
|
+
- sends notification (if set up)
|
31
|
+
|
32
|
+
### What it does (when uses `#publish_later`):
|
33
|
+
- takes in the `original_attributes`, `object_class`, `debounce_time`, `event`
|
34
|
+
- serializes the `original_attributes`, silently filters out unserializable keys/values
|
35
|
+
- enqueues (or skips) the job with the `serialized_original_attributes` to be performed in time according to debounce
|
36
|
+
- job (if enqueued) calls `TableSync::Publishing::Single#publish_now` with `serialized_original_attributes` and the same `object_class`, `debounce_time`, `event`
|
37
|
+
|
38
|
+
### Serialization
|
39
|
+
|
40
|
+
Currently allowed key/values are:
|
41
|
+
`NilClass`, `String`, `TrueClass`, `FalseClass`, `Numeric`, `Symbol`.
|
42
|
+
|
43
|
+
### Job
|
44
|
+
|
45
|
+
Job is defined in `TableSync.single_publishing_job_class_callable` as a proc. Read more in [Configuration](docs/publishing/configuration.md).
|
46
|
+
|
47
|
+
### Example #1 (send right now)
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
TableSync::Publishing::Single.new(
|
51
|
+
object_class: "User",
|
52
|
+
original_attributes: { id: 1, name: "Mark" },
|
53
|
+
debounce_time: 60, # useless for #publish _now, can be skipped
|
54
|
+
event: :create,
|
55
|
+
).publish_now
|
56
|
+
```
|
57
|
+
|
58
|
+
### Example #2 (enqueue job)
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
TableSync::Publishing::Single.new(
|
62
|
+
object_class: "User",
|
63
|
+
original_attributes: { id: 1, name: "Mark" }, # will be serialized!
|
64
|
+
debounce_time: 60,
|
65
|
+
event: :update,
|
66
|
+
).publish_later
|
67
|
+
```
|
68
|
+
|
69
|
+
## Batch
|
70
|
+
|
71
|
+
- `TableSync::Publishing::Batch` - sends a batch of rows with initialization.
|
72
|
+
|
73
|
+
### Expected parameters:
|
74
|
+
|
75
|
+
- `object_class` - class (model) used to initialize published objects
|
76
|
+
- `original_attributes` - array of attributes used to initialize `object_class` with
|
77
|
+
- `event` - type of event that happened to the published objects (`create`, `update`, `destroy`); `update` by default
|
78
|
+
- `routing_key` - custom routing_key
|
79
|
+
- `headers` - custom headers
|
80
|
+
|
81
|
+
### What it does (when uses `#publish_now`):
|
82
|
+
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
83
|
+
- constantizes `object_class`
|
84
|
+
- extracts primary keys (`needles`) of the `object_class` from the array of `original_attributes`
|
85
|
+
- queries the database for the objects with `needles` (for `update` and `create`) or initializes the `object_class` with `original_attributes` (for `destroy`)
|
86
|
+
- constructs routing_key using `routing_key_callable` (ignores `#attributes_for_routing_key`) or uses `routing_key` if given
|
87
|
+
- constructs headers using `headers_callable` (ignores `#attributes_for_headers`) or uses `headers` if given
|
88
|
+
- publishes Rabbit message (uses attributes from queried/initialized objects as data)
|
89
|
+
- sends notification (if set up)
|
90
|
+
|
91
|
+
### What it does (when uses `#publish_later`):
|
92
|
+
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
93
|
+
- serializes the array of `original_attributes`, silently filters out unserializable keys/values
|
94
|
+
- enqueues the job with the `serialized_original_attributes`
|
95
|
+
- job calls `TableSync::Publishing::Batch#publish_now` with `serialized_original_attributes` and the same `object_class`, `event`, `routing_key`, `headers`
|
96
|
+
|
97
|
+
### Serialization
|
98
|
+
|
99
|
+
Currently allowed key/values are:
|
100
|
+
`NilClass`, `String`, `TrueClass`, `FalseClass`, `Numeric`, `Symbol`.
|
101
|
+
|
102
|
+
### Job
|
103
|
+
|
104
|
+
Job is defined in `TableSync.batch_publishing_job_class_callable` as a proc. Read more in [Configuration](docs/publishing/configuration.md).
|
105
|
+
|
106
|
+
### Example #1 (send right now)
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
TableSync::Publishing::Batch.new(
|
110
|
+
object_class: "User",
|
111
|
+
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
112
|
+
event: :create,
|
113
|
+
routing_key: :custom_key, # optional
|
114
|
+
headers: { type: "admin" }, # optional
|
115
|
+
).publish_now
|
116
|
+
```
|
117
|
+
|
118
|
+
### Example #2 (enqueue job)
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
TableSync::Publishing::Batch.new(
|
122
|
+
object_class: "User",
|
123
|
+
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
124
|
+
event: :create,
|
125
|
+
routing_key: :custom_key, # optional
|
126
|
+
headers: { type: "admin" }, # optional
|
127
|
+
).publish_later
|
128
|
+
```
|
129
|
+
|
130
|
+
## Raw
|
131
|
+
- `TableSync::Publishing::Raw` - sends raw data without checks.
|
132
|
+
|
133
|
+
Be carefull with this publisher. There are no checks for the data sent.
|
134
|
+
You can send anything.
|
135
|
+
|
136
|
+
### Expected parameters:
|
137
|
+
|
138
|
+
- `object_class` - model
|
139
|
+
- `original_attributes` - raw data that will be sent
|
140
|
+
- `event` - type of event that happened to the published objects (`create`, `update`, `destroy`); `update` by default
|
141
|
+
- `routing_key` - custom routing_key
|
142
|
+
- `headers` - custom headers
|
143
|
+
|
144
|
+
### What it does (when uses `#publish_now`):
|
145
|
+
- takes in the `original_attributes`, `object_class`, `event`, `routing_key`, `headers`
|
146
|
+
- constantizes `object_class`
|
147
|
+
- constructs routing_key using `routing_key_callable` (ignores `#attributes_for_routing_key`) or uses `routing_key` if given
|
148
|
+
- constructs headers using `headers_callable` (ignores `#attributes_for_headers`) or uses `headers` if given
|
149
|
+
- publishes Rabbit message (uses `original_attributes` as is)
|
150
|
+
- sends notification (if set up)
|
151
|
+
|
152
|
+
### Example
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
TableSync::Publishing::Raw.new(
|
156
|
+
object_class: "User",
|
157
|
+
original_attributes: [{ id: 1, name: "Mark" }, { id: 2, name: "Bob" }],
|
158
|
+
event: :create,
|
159
|
+
routing_key: :custom_key, # optional
|
160
|
+
headers: { type: "admin" }, # optional
|
161
|
+
).publish_now
|
162
|
+
```
|