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
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# CASES FOR DEBOUNCE
|
4
|
+
|
5
|
+
# Cached Sync Time -> CST - time last sync has occured or next sync will occur
|
6
|
+
# Next Sync Time -> NST - time next sync will occur
|
7
|
+
|
8
|
+
# 0
|
9
|
+
# Condition: debounce_time is zero.
|
10
|
+
# No debounce, sync right now.
|
11
|
+
# Result: NST -> Time.current
|
12
|
+
|
13
|
+
# 1
|
14
|
+
# Condition: CST is empty.
|
15
|
+
# There was no sync before. Can be synced right now.
|
16
|
+
# Result: NST -> Time.current
|
17
|
+
|
18
|
+
# 2
|
19
|
+
# Condition: CST =< Time.current.
|
20
|
+
# There was a sync before.
|
21
|
+
|
22
|
+
# 2.1
|
23
|
+
# Subcondition: CST + debounce_time <= Time.current
|
24
|
+
# Enough time passed for debounce condition to be satisfied.
|
25
|
+
# No need to wait. Can by synced right now.
|
26
|
+
# Result: NST -> Time.current
|
27
|
+
|
28
|
+
# 2.2
|
29
|
+
# Subcondition: CST + debounce_time > Time.current
|
30
|
+
# Debounce condition is not satisfied. Must wait till debounce period has passed.
|
31
|
+
# Will be synced after debounce period has passed.
|
32
|
+
# Result: NST -> CST + debounce_time
|
33
|
+
|
34
|
+
# 3
|
35
|
+
# Condition: CST > Time.current
|
36
|
+
# Sync job has already been enqueued in the future.
|
37
|
+
|
38
|
+
# 3.1
|
39
|
+
# Subcondition: event -> update | create
|
40
|
+
# No need to sync upsert event, since it has already enqueued sync in the future.
|
41
|
+
# It will sync fresh version anyway.
|
42
|
+
# NST -> Skip, no sync.
|
43
|
+
|
44
|
+
# 3.2
|
45
|
+
# Subcondition: event -> destroy
|
46
|
+
# In this case the already enqueued job must be upsert.
|
47
|
+
# Thus destructive sync has to send message after upsert sync.
|
48
|
+
# NST -> CST + debounce_time
|
49
|
+
|
50
|
+
module TableSync::Publishing::Helpers
|
51
|
+
class Debounce
|
52
|
+
include Memery
|
53
|
+
|
54
|
+
DEFAULT_TIME = 60
|
55
|
+
|
56
|
+
attr_reader :debounce_time, :object_class, :needle, :event
|
57
|
+
|
58
|
+
def initialize(object_class:, needle:, event:, debounce_time: nil)
|
59
|
+
@event = event
|
60
|
+
@debounce_time = debounce_time || DEFAULT_TIME
|
61
|
+
@object_class = object_class
|
62
|
+
@needle = needle
|
63
|
+
end
|
64
|
+
|
65
|
+
def skip?
|
66
|
+
true if sync_in_the_future? && upsert_event? # case 3.1
|
67
|
+
end
|
68
|
+
|
69
|
+
memoize def next_sync_time
|
70
|
+
return current_time if debounce_time.zero? # case 0
|
71
|
+
return current_time if no_sync_before? # case 1
|
72
|
+
|
73
|
+
return current_time if sync_in_the_past? && debounce_time_passed? # case 2.1
|
74
|
+
return debounced_sync_time if sync_in_the_past? && debounce_time_not_passed? # case 2.2
|
75
|
+
|
76
|
+
return debounced_sync_time if sync_in_the_future? && destroy_event? # case 3.2
|
77
|
+
end
|
78
|
+
|
79
|
+
# CASE 1
|
80
|
+
def no_sync_before?
|
81
|
+
cached_sync_time.nil?
|
82
|
+
end
|
83
|
+
|
84
|
+
# CASE 2
|
85
|
+
def sync_in_the_past?
|
86
|
+
cached_sync_time <= current_time
|
87
|
+
end
|
88
|
+
|
89
|
+
def debounce_time_passed?
|
90
|
+
cached_sync_time + debounce_time.seconds >= current_time
|
91
|
+
end
|
92
|
+
|
93
|
+
def debounce_time_not_passed?
|
94
|
+
cached_sync_time + debounce_time.seconds < current_time
|
95
|
+
end
|
96
|
+
|
97
|
+
# CASE 3
|
98
|
+
def sync_in_the_future?
|
99
|
+
cached_sync_time && (cached_sync_time > current_time)
|
100
|
+
end
|
101
|
+
|
102
|
+
def destroy_event?
|
103
|
+
event == :destroy
|
104
|
+
end
|
105
|
+
|
106
|
+
def upsert_event?
|
107
|
+
!destroy_event?
|
108
|
+
end
|
109
|
+
|
110
|
+
# MISC
|
111
|
+
|
112
|
+
def debounced_sync_time
|
113
|
+
cached_sync_time + debounce_time.seconds
|
114
|
+
end
|
115
|
+
|
116
|
+
memoize def current_time
|
117
|
+
Time.current
|
118
|
+
end
|
119
|
+
|
120
|
+
# CACHE
|
121
|
+
|
122
|
+
memoize def cached_sync_time
|
123
|
+
Rails.cache.read(cache_key)
|
124
|
+
end
|
125
|
+
|
126
|
+
def cache_next_sync_time
|
127
|
+
Rails.cache.write(cache_key, next_sync_time)
|
128
|
+
end
|
129
|
+
|
130
|
+
def cache_key
|
131
|
+
"#{object_class}/#{needle.values.join}_table_sync_time".delete(" ")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Helpers
|
4
|
+
class Objects
|
5
|
+
attr_reader :object_class, :original_attributes, :event
|
6
|
+
|
7
|
+
def initialize(object_class:, original_attributes:, event:)
|
8
|
+
@event = TableSync::Event.new(event)
|
9
|
+
@object_class = object_class.constantize
|
10
|
+
@original_attributes = Array.wrap(original_attributes)
|
11
|
+
end
|
12
|
+
|
13
|
+
def construct_list
|
14
|
+
if event.destroy?
|
15
|
+
init_objects
|
16
|
+
else
|
17
|
+
without_empty_objects(find_objects)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def without_empty_objects(objects)
|
24
|
+
objects.reject(&:empty?)
|
25
|
+
end
|
26
|
+
|
27
|
+
def init_objects
|
28
|
+
original_attributes.map do |attrs|
|
29
|
+
TableSync.publishing_adapter.new(object_class, attrs).init
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_objects
|
34
|
+
original_attributes.map do |attrs|
|
35
|
+
TableSync.publishing_adapter.new(object_class, attrs).find
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Base
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attr_reader :objects
|
8
|
+
|
9
|
+
attribute :object_class
|
10
|
+
attribute :original_attributes
|
11
|
+
attribute :event
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
super(params)
|
15
|
+
|
16
|
+
@objects = find_or_init_objects
|
17
|
+
|
18
|
+
raise TableSync::NoObjectsForSyncError if objects.empty? && TableSync.raise_on_empty_message
|
19
|
+
end
|
20
|
+
|
21
|
+
def publish
|
22
|
+
return if original_attributes.blank?
|
23
|
+
|
24
|
+
Rabbit.publish(message_params)
|
25
|
+
|
26
|
+
notify!
|
27
|
+
end
|
28
|
+
|
29
|
+
def empty?
|
30
|
+
objects.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_or_init_objects
|
34
|
+
TableSync::Publishing::Helpers::Objects.new(
|
35
|
+
object_class: object_class, original_attributes: original_attributes, event: event,
|
36
|
+
).construct_list
|
37
|
+
end
|
38
|
+
|
39
|
+
# MESSAGE PARAMS
|
40
|
+
|
41
|
+
def message_params
|
42
|
+
params.merge(data: data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def data
|
46
|
+
TableSync::Publishing::Data::Objects.new(
|
47
|
+
objects: objects, event: event,
|
48
|
+
).construct
|
49
|
+
end
|
50
|
+
|
51
|
+
# :nocov:
|
52
|
+
def params
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
# :nocov:
|
56
|
+
|
57
|
+
# NOTIFY
|
58
|
+
|
59
|
+
def notify!
|
60
|
+
TableSync::Instrument.notify(
|
61
|
+
table: model_naming.table,
|
62
|
+
schema: model_naming.schema,
|
63
|
+
event: event,
|
64
|
+
direction: :publish,
|
65
|
+
count: objects.count,
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def model_naming
|
70
|
+
TableSync.publishing_adapter.model_naming(objects.first.object_class)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Batch < Base
|
5
|
+
attribute :headers
|
6
|
+
attribute :routing_key
|
7
|
+
|
8
|
+
def params
|
9
|
+
TableSync::Publishing::Params::Batch.new(
|
10
|
+
object_class: object_class, headers: headers, routing_key: routing_key,
|
11
|
+
).construct
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Raw
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
attribute :original_attributes
|
9
|
+
attribute :routing_key
|
10
|
+
attribute :headers
|
11
|
+
|
12
|
+
attribute :event
|
13
|
+
|
14
|
+
def publish
|
15
|
+
Rabbit.publish(message_params)
|
16
|
+
|
17
|
+
notify!
|
18
|
+
end
|
19
|
+
|
20
|
+
# NOTIFY
|
21
|
+
|
22
|
+
def notify!
|
23
|
+
TableSync::Instrument.notify(
|
24
|
+
table: model_naming.table,
|
25
|
+
schema: model_naming.schema,
|
26
|
+
event: event,
|
27
|
+
count: original_attributes.count,
|
28
|
+
direction: :publish,
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def model_naming
|
33
|
+
TableSync.publishing_adapter.model_naming(object_class.constantize)
|
34
|
+
end
|
35
|
+
|
36
|
+
# MESSAGE PARAMS
|
37
|
+
|
38
|
+
def message_params
|
39
|
+
params.merge(data: data)
|
40
|
+
end
|
41
|
+
|
42
|
+
def data
|
43
|
+
TableSync::Publishing::Data::Raw.new(
|
44
|
+
object_class: object_class, attributes_for_sync: original_attributes, event: event,
|
45
|
+
).construct
|
46
|
+
end
|
47
|
+
|
48
|
+
def params
|
49
|
+
TableSync::Publishing::Params::Raw.new(
|
50
|
+
object_class: object_class, routing_key: routing_key, headers: headers,
|
51
|
+
).construct
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Base
|
5
|
+
DEFAULT_PARAMS = {
|
6
|
+
confirm_select: true,
|
7
|
+
realtime: true,
|
8
|
+
event: :table_sync,
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
def construct
|
12
|
+
DEFAULT_PARAMS.merge(
|
13
|
+
routing_key: routing_key,
|
14
|
+
headers: headers,
|
15
|
+
exchange_name: exchange_name,
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def calculated_routing_key
|
22
|
+
if TableSync.routing_key_callable
|
23
|
+
TableSync.routing_key_callable.call(object_class, attributes_for_routing_key)
|
24
|
+
else
|
25
|
+
raise TableSync::NoCallableError.new("routing_key")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def calculated_headers
|
30
|
+
if TableSync.headers_callable
|
31
|
+
TableSync.headers_callable.call(object_class, attributes_for_headers)
|
32
|
+
else
|
33
|
+
raise TableSync::NoCallableError.new("headers")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# NOT IMPLEMENTED
|
38
|
+
|
39
|
+
# name of the model being synced in the string format
|
40
|
+
# :nocov:
|
41
|
+
def object_class
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
def routing_key
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
def headers
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
def exchange_name
|
54
|
+
raise NotImplementedError
|
55
|
+
end
|
56
|
+
|
57
|
+
def attributes_for_routing_key
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
def attributes_for_headers
|
62
|
+
raise NotImplementedError
|
63
|
+
end
|
64
|
+
# :nocov:
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Batch < Base
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
|
9
|
+
attribute :exchange_name, default: -> { TableSync.exchange_name }
|
10
|
+
attribute :routing_key, default: -> { calculated_routing_key }
|
11
|
+
attribute :headers, default: -> { calculated_headers }
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def attributes_for_routing_key
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes_for_headers
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Single < Base
|
5
|
+
attr_reader :object, :routing_key, :headers
|
6
|
+
|
7
|
+
def initialize(object:)
|
8
|
+
@object = object
|
9
|
+
@routing_key = calculated_routing_key
|
10
|
+
@headers = calculated_headers
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def object_class
|
16
|
+
object.object_class.name
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes_for_routing_key
|
20
|
+
object.attributes_for_routing_key
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes_for_headers
|
24
|
+
object.attributes_for_headers
|
25
|
+
end
|
26
|
+
|
27
|
+
def exchange_name
|
28
|
+
TableSync.exchange_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TableSync::Publishing::Raw
|
4
|
+
include Tainbox
|
5
|
+
|
6
|
+
attribute :object_class
|
7
|
+
attribute :original_attributes
|
8
|
+
|
9
|
+
attribute :routing_key
|
10
|
+
attribute :headers
|
11
|
+
|
12
|
+
attribute :event, default: :update
|
13
|
+
|
14
|
+
def publish_now
|
15
|
+
message.publish
|
16
|
+
end
|
17
|
+
|
18
|
+
def message
|
19
|
+
TableSync::Publishing::Message::Raw.new(attributes)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TableSync::Publishing::Single
|
4
|
+
include Tainbox
|
5
|
+
include Memery
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
attribute :original_attributes
|
9
|
+
attribute :debounce_time
|
10
|
+
|
11
|
+
attribute :event, Symbol, default: :update
|
12
|
+
|
13
|
+
# expect job to have perform_at method
|
14
|
+
# debounce destroyed event
|
15
|
+
# because otherwise update event could be sent after destroy
|
16
|
+
def publish_later
|
17
|
+
return if debounce.skip?
|
18
|
+
|
19
|
+
job.perform_at(job_attributes)
|
20
|
+
|
21
|
+
debounce.cache_next_sync_time
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish_now
|
25
|
+
message.publish unless message.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
memoize def message
|
29
|
+
TableSync::Publishing::Message::Single.new(attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
memoize def debounce
|
33
|
+
TableSync::Publishing::Helpers::Debounce.new(
|
34
|
+
object_class: object_class,
|
35
|
+
needle: message.object.needle,
|
36
|
+
debounce_time: debounce_time,
|
37
|
+
event: event,
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# JOB
|
44
|
+
|
45
|
+
def job
|
46
|
+
if TableSync.single_publishing_job_class_callable
|
47
|
+
TableSync.single_publishing_job_class_callable.call
|
48
|
+
else
|
49
|
+
raise TableSync::NoCallableError.new("single_publishing_job_class")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def job_attributes
|
54
|
+
attributes.merge(
|
55
|
+
original_attributes: serialized_original_attributes,
|
56
|
+
perform_at: debounce.next_sync_time,
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def serialized_original_attributes
|
61
|
+
TableSync::Publishing::Helpers::Attributes
|
62
|
+
.new(original_attributes)
|
63
|
+
.serialize
|
64
|
+
end
|
65
|
+
end
|
@@ -2,10 +2,25 @@
|
|
2
2
|
|
3
3
|
module TableSync
|
4
4
|
module Publishing
|
5
|
-
require_relative "publishing/
|
6
|
-
require_relative "publishing/
|
7
|
-
|
8
|
-
require_relative "publishing/
|
9
|
-
require_relative "publishing/
|
5
|
+
require_relative "publishing/data/objects"
|
6
|
+
require_relative "publishing/data/raw"
|
7
|
+
|
8
|
+
require_relative "publishing/helpers/attributes"
|
9
|
+
require_relative "publishing/helpers/debounce"
|
10
|
+
require_relative "publishing/helpers/objects"
|
11
|
+
|
12
|
+
require_relative "publishing/params/base"
|
13
|
+
require_relative "publishing/params/batch"
|
14
|
+
require_relative "publishing/params/raw"
|
15
|
+
require_relative "publishing/params/single"
|
16
|
+
|
17
|
+
require_relative "publishing/message/base"
|
18
|
+
require_relative "publishing/message/batch"
|
19
|
+
require_relative "publishing/message/raw"
|
20
|
+
require_relative "publishing/message/single"
|
21
|
+
|
22
|
+
require_relative "publishing/batch"
|
23
|
+
require_relative "publishing/raw"
|
24
|
+
require_relative "publishing/single"
|
10
25
|
end
|
11
26
|
end
|
@@ -4,20 +4,22 @@ module TableSync::Receiving
|
|
4
4
|
class Config
|
5
5
|
attr_reader :model, :events
|
6
6
|
|
7
|
-
def initialize(model:, events:
|
7
|
+
def initialize(model:, events: TableSync::Event::VALID_RESOLVED_EVENTS)
|
8
8
|
@model = model
|
9
9
|
|
10
10
|
@events = [events].flatten.map(&:to_sym)
|
11
11
|
|
12
|
-
|
13
|
-
raise TableSync::UndefinedEvent.new(events)
|
14
|
-
end
|
12
|
+
raise TableSync::UndefinedEvent.new(events) if invalid_events.any?
|
15
13
|
|
16
14
|
self.class.default_values_for_options.each do |ivar, default_value_generator|
|
17
15
|
instance_variable_set(ivar, default_value_generator.call(self))
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
19
|
+
def invalid_events
|
20
|
+
events - TableSync::Event::VALID_RESOLVED_EVENTS
|
21
|
+
end
|
22
|
+
|
21
23
|
class << self
|
22
24
|
attr_reader :default_values_for_options
|
23
25
|
|
@@ -44,14 +44,18 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
44
44
|
super(Array.wrap(data[:attributes]))
|
45
45
|
end
|
46
46
|
|
47
|
-
def event=(
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
def event=(event_name)
|
48
|
+
event_name = event_name.to_sym
|
49
|
+
|
50
|
+
if event_name.in?(TableSync::Event::VALID_RESOLVED_EVENTS)
|
51
|
+
super(event_name)
|
52
|
+
else
|
53
|
+
raise TableSync::UndefinedEvent.new(event)
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
|
-
def model=(
|
54
|
-
super(
|
57
|
+
def model=(model_name)
|
58
|
+
super(model_name.to_s)
|
55
59
|
end
|
56
60
|
|
57
61
|
def configs
|
data/lib/table_sync/receiving.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Setup
|
4
|
+
class ActiveRecord < Base
|
5
|
+
private
|
6
|
+
|
7
|
+
def define_after_commit(event)
|
8
|
+
options = options_exposed_for_block
|
9
|
+
|
10
|
+
object_class.after_commit(on: event) do
|
11
|
+
if instance_eval(&options[:if]) && !instance_eval(&options[:unless])
|
12
|
+
TableSync::Publishing::Single.new(
|
13
|
+
object_class: self.class.name,
|
14
|
+
original_attributes: attributes,
|
15
|
+
event: event,
|
16
|
+
debounce_time: options[:debounce_time],
|
17
|
+
).publish_later
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|