ruby_event_store-outbox 0.0.10 → 0.0.15
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/lib/generators/ruby_event_store/outbox/templates/create_event_store_outbox_template.rb +8 -0
- data/lib/ruby_event_store/outbox.rb +1 -0
- data/lib/ruby_event_store/outbox/cli.rb +3 -1
- data/lib/ruby_event_store/outbox/consumer.rb +122 -46
- data/lib/ruby_event_store/outbox/consumer_process.rb +6 -0
- data/lib/ruby_event_store/outbox/fetch_specification.rb +13 -0
- data/lib/ruby_event_store/outbox/metrics/influx.rb +16 -2
- data/lib/ruby_event_store/outbox/metrics/null.rb +3 -0
- data/lib/ruby_event_store/outbox/record.rb +87 -0
- data/lib/ruby_event_store/outbox/sidekiq_processor.rb +44 -0
- data/lib/ruby_event_store/outbox/sidekiq_producer.rb +27 -0
- data/lib/ruby_event_store/outbox/sidekiq_scheduler.rb +9 -16
- data/lib/ruby_event_store/outbox/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4c373da7338563c51f8bc7d3bae7e56ceb99f9b75d8104196d003f5316cdb6a
|
4
|
+
data.tar.gz: fbb6dad9bdaee2fea028a2cea8541eb6a9f964e1d10d4e704ebe3f715a88d623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6f7ac3498d139a98ef14b8cbb7abe7bd4af8b794b41f90c6b65150523410a25a59ff6e863301d87f3a90bb5be80cc422d7ae94dd8a16fedd3b88a1db334eee0
|
7
|
+
data.tar.gz: 1c30a1e0c60bee39d1064e0aa7c535416a3cca7d4aa25328ab684741bf4a6bc65373e412388e65d5e57183a4dbf25e4fff385c456cd562c1afc2fe9e04e1d5d8
|
@@ -11,5 +11,13 @@ class CreateEventStoreOutbox < ActiveRecord::Migration<%= migration_version %>
|
|
11
11
|
end
|
12
12
|
add_index :event_store_outbox, [:format, :enqueued_at, :split_key], name: "index_event_store_outbox_for_pool"
|
13
13
|
add_index :event_store_outbox, [:created_at, :enqueued_at], name: "index_event_store_outbox_for_clear"
|
14
|
+
|
15
|
+
create_table(:event_store_outbox_locks, force: false) do |t|
|
16
|
+
t.string :format, null: false
|
17
|
+
t.string :split_key, null: false
|
18
|
+
t.datetime :locked_at, null: true
|
19
|
+
t.string :locked_by, null: true, limit: 36
|
20
|
+
end
|
21
|
+
add_index :event_store_outbox_locks, [:format, :split_key], name: "index_event_store_outbox_locks_for_locking", unique: true
|
14
22
|
end
|
15
23
|
end
|
@@ -59,7 +59,8 @@ module RubyEventStore
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def build_consumer(options)
|
62
|
-
|
62
|
+
consumer_uuid = SecureRandom.uuid
|
63
|
+
logger = Logger.new(STDOUT, level: options.log_level, progname: "RES-Outbox #{consumer_uuid}")
|
63
64
|
consumer_configuration = Consumer::Configuration.new(
|
64
65
|
split_keys: options.split_keys,
|
65
66
|
message_format: options.message_format,
|
@@ -69,6 +70,7 @@ module RubyEventStore
|
|
69
70
|
)
|
70
71
|
metrics = Metrics.from_url(options.metrics_url)
|
71
72
|
outbox_consumer = RubyEventStore::Outbox::Consumer.new(
|
73
|
+
consumer_uuid,
|
72
74
|
options,
|
73
75
|
logger: logger,
|
74
76
|
metrics: metrics,
|
@@ -3,11 +3,14 @@ require "redis"
|
|
3
3
|
require "active_record"
|
4
4
|
require "ruby_event_store/outbox/record"
|
5
5
|
require "ruby_event_store/outbox/sidekiq5_format"
|
6
|
+
require "ruby_event_store/outbox/sidekiq_processor"
|
7
|
+
require "ruby_event_store/outbox/fetch_specification"
|
6
8
|
|
7
9
|
module RubyEventStore
|
8
10
|
module Outbox
|
9
11
|
class Consumer
|
10
|
-
SLEEP_TIME_WHEN_NOTHING_TO_DO = 0.
|
12
|
+
SLEEP_TIME_WHEN_NOTHING_TO_DO = 0.5
|
13
|
+
MAXIMUM_BATCH_FETCHES_IN_ONE_LOCK = 10
|
11
14
|
|
12
15
|
class Configuration
|
13
16
|
def initialize(
|
@@ -38,28 +41,26 @@ module RubyEventStore
|
|
38
41
|
attr_reader :split_keys, :message_format, :batch_size, :database_url, :redis_url
|
39
42
|
end
|
40
43
|
|
41
|
-
def initialize(configuration, clock: Time, logger:, metrics:)
|
44
|
+
def initialize(consumer_uuid, configuration, clock: Time, logger:, metrics:)
|
42
45
|
@split_keys = configuration.split_keys
|
43
46
|
@clock = clock
|
44
|
-
@redis = Redis.new(url: configuration.redis_url)
|
45
47
|
@logger = logger
|
46
48
|
@metrics = metrics
|
47
49
|
@batch_size = configuration.batch_size
|
50
|
+
@consumer_uuid = consumer_uuid
|
48
51
|
ActiveRecord::Base.establish_connection(configuration.database_url) unless ActiveRecord::Base.connected?
|
49
52
|
if ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
50
|
-
ActiveRecord::Base.connection.execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;")
|
51
53
|
ActiveRecord::Base.connection.execute("SET SESSION innodb_lock_wait_timeout = 1;")
|
52
54
|
end
|
53
55
|
|
54
56
|
raise "Unknown format" if configuration.message_format != SIDEKIQ5_FORMAT
|
55
|
-
@
|
57
|
+
@processor = SidekiqProcessor.new(Redis.new(url: configuration.redis_url))
|
56
58
|
|
57
59
|
@gracefully_shutting_down = false
|
58
60
|
prepare_traps
|
59
61
|
end
|
60
62
|
|
61
63
|
def init
|
62
|
-
@redis.sadd("queues", split_keys)
|
63
64
|
logger.info("Initiated RubyEventStore::Outbox v#{VERSION}")
|
64
65
|
logger.info("Handling split keys: #{split_keys ? split_keys.join(", ") : "(all of them)"}")
|
65
66
|
end
|
@@ -76,62 +77,129 @@ module RubyEventStore
|
|
76
77
|
end
|
77
78
|
|
78
79
|
def one_loop
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
80
|
+
remaining_split_keys = @split_keys.dup
|
81
|
+
|
82
|
+
was_something_changed = false
|
83
|
+
while (split_key = remaining_split_keys.shift)
|
84
|
+
was_something_changed |= handle_split(FetchSpecification.new(processor.message_format, split_key))
|
85
|
+
end
|
86
|
+
was_something_changed
|
87
|
+
end
|
88
|
+
|
89
|
+
def handle_split(fetch_specification)
|
90
|
+
obtained_lock = obtain_lock_for_process(fetch_specification)
|
91
|
+
return false unless obtained_lock
|
92
|
+
|
93
|
+
something_processed = false
|
94
|
+
|
95
|
+
MAXIMUM_BATCH_FETCHES_IN_ONE_LOCK.times do
|
96
|
+
batch = retrieve_batch(fetch_specification)
|
97
|
+
if batch.empty?
|
98
|
+
break
|
86
99
|
end
|
87
100
|
|
88
|
-
now = @clock.now.utc
|
89
101
|
failed_record_ids = []
|
90
|
-
|
102
|
+
updated_record_ids = []
|
103
|
+
batch.each do |record|
|
91
104
|
begin
|
92
|
-
|
93
|
-
|
105
|
+
now = @clock.now.utc
|
106
|
+
processor.process(record, now)
|
107
|
+
|
108
|
+
record.update_column(:enqueued_at, now)
|
109
|
+
something_processed |= true
|
110
|
+
updated_record_ids << record.id
|
94
111
|
rescue => e
|
95
|
-
failed_record_ids.
|
112
|
+
failed_record_ids << record.id
|
96
113
|
e.full_message.split($/).each {|line| logger.error(line) }
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
100
|
-
|
101
|
-
|
102
|
-
|
117
|
+
metrics.write_point_queue(
|
118
|
+
enqueued: updated_record_ids.size,
|
119
|
+
failed: failed_record_ids.size,
|
120
|
+
format: fetch_specification.message_format,
|
121
|
+
split_key: fetch_specification.split_key,
|
122
|
+
remaining: get_remaining_count(fetch_specification)
|
123
|
+
)
|
103
124
|
|
104
125
|
logger.info "Sent #{updated_record_ids.size} messages from outbox table"
|
105
|
-
|
126
|
+
|
127
|
+
obtained_lock = refresh_lock_for_process(obtained_lock)
|
128
|
+
break unless obtained_lock
|
106
129
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
130
|
+
|
131
|
+
metrics.write_point_queue(
|
132
|
+
format: fetch_specification.message_format,
|
133
|
+
split_key: fetch_specification.split_key,
|
134
|
+
remaining: get_remaining_count(fetch_specification)
|
135
|
+
) unless something_processed
|
136
|
+
|
137
|
+
release_lock_for_process(fetch_specification)
|
138
|
+
|
139
|
+
processor.after_batch
|
140
|
+
|
141
|
+
something_processed
|
115
142
|
end
|
116
143
|
|
117
144
|
private
|
118
|
-
attr_reader :split_keys, :logger, :
|
119
|
-
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
145
|
+
attr_reader :split_keys, :logger, :batch_size, :metrics, :processor, :consumer_uuid
|
146
|
+
|
147
|
+
def obtain_lock_for_process(fetch_specification)
|
148
|
+
result = Lock.obtain(fetch_specification, consumer_uuid, clock: @clock)
|
149
|
+
case result
|
150
|
+
when :deadlocked
|
151
|
+
logger.warn "Obtaining lock for split_key '#{fetch_specification.split_key}' failed (deadlock)"
|
152
|
+
metrics.write_operation_result("obtain", "deadlocked")
|
153
|
+
return false
|
154
|
+
when :lock_timeout
|
155
|
+
logger.warn "Obtaining lock for split_key '#{fetch_specification.split_key}' failed (lock timeout)"
|
156
|
+
metrics.write_operation_result("obtain", "lock_timeout")
|
157
|
+
return false
|
158
|
+
when :taken
|
159
|
+
logger.debug "Obtaining lock for split_key '#{fetch_specification.split_key}' unsuccessful (taken)"
|
160
|
+
metrics.write_operation_result("obtain", "taken")
|
161
|
+
return false
|
162
|
+
else
|
163
|
+
return result
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def release_lock_for_process(fetch_specification)
|
168
|
+
result = Lock.release(fetch_specification, consumer_uuid)
|
169
|
+
case result
|
170
|
+
when :ok
|
171
|
+
when :deadlocked
|
172
|
+
logger.warn "Releasing lock for split_key '#{fetch_specification.split_key}' failed (deadlock)"
|
173
|
+
metrics.write_operation_result("release", "deadlocked")
|
174
|
+
when :lock_timeout
|
175
|
+
logger.warn "Releasing lock for split_key '#{fetch_specification.split_key}' failed (lock timeout)"
|
176
|
+
metrics.write_operation_result("release", "lock_timeout")
|
177
|
+
when :not_taken_by_this_process
|
178
|
+
logger.debug "Releasing lock for split_key '#{fetch_specification.split_key}' failed (not taken by this process)"
|
179
|
+
metrics.write_operation_result("release", "not_taken_by_this_process")
|
180
|
+
else
|
181
|
+
raise "Unexpected result #{result}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def refresh_lock_for_process(lock)
|
186
|
+
result = lock.refresh(clock: @clock)
|
187
|
+
case result
|
188
|
+
when :deadlocked
|
189
|
+
logger.warn "Refreshing lock for split_key '#{lock.split_key}' failed (deadlock)"
|
190
|
+
metrics.write_operation_result("refresh", "deadlocked")
|
191
|
+
return false
|
192
|
+
when :lock_timeout
|
193
|
+
logger.warn "Refreshing lock for split_key '#{lock.split_key}' failed (lock timeout)"
|
194
|
+
metrics.write_operation_result("refresh", "lock_timeout")
|
195
|
+
return false
|
196
|
+
when :stolen
|
197
|
+
logger.debug "Refreshing lock for split_key '#{lock.split_key}' unsuccessful (stolen)"
|
198
|
+
metrics.write_operation_result("refresh", "stolen")
|
199
|
+
return false
|
200
|
+
else
|
201
|
+
return result
|
132
202
|
end
|
133
|
-
@redis.lpush("queue:#{split_key}", elements)
|
134
|
-
failed
|
135
203
|
end
|
136
204
|
|
137
205
|
def prepare_traps
|
@@ -146,6 +214,14 @@ module RubyEventStore
|
|
146
214
|
def initiate_graceful_shutdown
|
147
215
|
@gracefully_shutting_down = true
|
148
216
|
end
|
217
|
+
|
218
|
+
def retrieve_batch(fetch_specification)
|
219
|
+
Record.remaining_for(fetch_specification).order("id ASC").limit(batch_size).to_a
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_remaining_count(fetch_specification)
|
223
|
+
Record.remaining_for(fetch_specification).count
|
224
|
+
end
|
149
225
|
end
|
150
226
|
end
|
151
227
|
end
|
@@ -17,14 +17,28 @@ module RubyEventStore
|
|
17
17
|
@influxdb_client = InfluxDB::Client.new(**options)
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def write_operation_result(operation, result)
|
21
|
+
write_point("ruby_event_store.outbox.lock", {
|
22
|
+
values: {
|
23
|
+
value: 1,
|
24
|
+
},
|
25
|
+
tags: {
|
26
|
+
operation: operation,
|
27
|
+
result: result,
|
28
|
+
}
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_point_queue(enqueued: 0, failed: 0, remaining: 0, format: nil, split_key: nil)
|
21
33
|
write_point("ruby_event_store.outbox.queue", {
|
22
34
|
values: {
|
23
35
|
enqueued: enqueued,
|
24
36
|
failed: failed,
|
37
|
+
remaining: remaining,
|
25
38
|
},
|
26
39
|
tags: {
|
27
|
-
|
40
|
+
format: format,
|
41
|
+
split_key: split_key,
|
28
42
|
}
|
29
43
|
})
|
30
44
|
end
|
@@ -8,9 +8,96 @@ module RubyEventStore
|
|
8
8
|
self.primary_key = :id
|
9
9
|
self.table_name = 'event_store_outbox'
|
10
10
|
|
11
|
+
def self.remaining_for(fetch_specification)
|
12
|
+
where(format: fetch_specification.message_format, split_key: fetch_specification.split_key, enqueued_at: nil)
|
13
|
+
end
|
14
|
+
|
11
15
|
def hash_payload
|
12
16
|
JSON.parse(payload).deep_symbolize_keys
|
13
17
|
end
|
18
|
+
|
19
|
+
def enqueued?
|
20
|
+
!enqueued_at.nil?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Lock < ::ActiveRecord::Base
|
25
|
+
self.table_name = 'event_store_outbox_locks'
|
26
|
+
|
27
|
+
def self.obtain(fetch_specification, process_uuid, clock:)
|
28
|
+
l = nil
|
29
|
+
transaction do
|
30
|
+
l = get_lock_record(fetch_specification)
|
31
|
+
|
32
|
+
return :taken if l.recently_locked?
|
33
|
+
|
34
|
+
l.update!(
|
35
|
+
locked_by: process_uuid,
|
36
|
+
locked_at: clock.now,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
l
|
40
|
+
rescue ActiveRecord::Deadlocked
|
41
|
+
:deadlocked
|
42
|
+
rescue ActiveRecord::LockWaitTimeout
|
43
|
+
:lock_timeout
|
44
|
+
end
|
45
|
+
|
46
|
+
def refresh(clock:)
|
47
|
+
transaction do
|
48
|
+
current_process_uuid = locked_by
|
49
|
+
lock!
|
50
|
+
if locked_by == current_process_uuid
|
51
|
+
update!(locked_at: clock.now)
|
52
|
+
return self
|
53
|
+
else
|
54
|
+
return :stolen
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue ActiveRecord::Deadlocked
|
58
|
+
:deadlocked
|
59
|
+
rescue ActiveRecord::LockWaitTimeout
|
60
|
+
:lock_timeout
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.release(fetch_specification, process_uuid)
|
64
|
+
transaction do
|
65
|
+
l = get_lock_record(fetch_specification)
|
66
|
+
return :not_taken_by_this_process if !l.locked_by?(process_uuid)
|
67
|
+
|
68
|
+
l.update!(locked_by: nil, locked_at: nil)
|
69
|
+
end
|
70
|
+
:ok
|
71
|
+
rescue ActiveRecord::Deadlocked
|
72
|
+
:deadlocked
|
73
|
+
rescue ActiveRecord::LockWaitTimeout
|
74
|
+
:lock_timeout
|
75
|
+
end
|
76
|
+
|
77
|
+
def locked_by?(process_uuid)
|
78
|
+
locked_by.eql?(process_uuid)
|
79
|
+
end
|
80
|
+
|
81
|
+
def recently_locked?
|
82
|
+
locked_by && locked_at > 10.minutes.ago
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
def self.lock_for_split_key(fetch_specification)
|
87
|
+
lock.find_by(format: fetch_specification.message_format, split_key: fetch_specification.split_key)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.get_lock_record(fetch_specification)
|
91
|
+
l = lock_for_split_key(fetch_specification)
|
92
|
+
if l.nil?
|
93
|
+
begin
|
94
|
+
l = create!(format: fetch_specification.message_format, split_key: fetch_specification.split_key)
|
95
|
+
rescue ActiveRecord::RecordNotUnique
|
96
|
+
l = lock_for_split_key(fetch_specification)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
l
|
100
|
+
end
|
14
101
|
end
|
15
102
|
end
|
16
103
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ruby_event_store/outbox/sidekiq5_format"
|
4
|
+
|
5
|
+
module RubyEventStore
|
6
|
+
module Outbox
|
7
|
+
class SidekiqProcessor
|
8
|
+
InvalidPayload = Class.new(StandardError)
|
9
|
+
|
10
|
+
def initialize(redis)
|
11
|
+
@redis = redis
|
12
|
+
@recently_used_queues = Set.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def process(record, now)
|
16
|
+
parsed_record = JSON.parse(record.payload)
|
17
|
+
|
18
|
+
queue = parsed_record["queue"]
|
19
|
+
raise InvalidPayload.new("Missing queue") if queue.nil? || queue.empty?
|
20
|
+
payload = JSON.generate(parsed_record.merge({
|
21
|
+
"enqueued_at" => now.to_f,
|
22
|
+
}))
|
23
|
+
|
24
|
+
redis.lpush("queue:#{queue}", payload)
|
25
|
+
|
26
|
+
@recently_used_queues << queue
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_batch
|
30
|
+
if !@recently_used_queues.empty?
|
31
|
+
redis.sadd("queues", @recently_used_queues.to_a)
|
32
|
+
@recently_used_queues.clear
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def message_format
|
37
|
+
SIDEKIQ5_FORMAT
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
attr_reader :redis
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sidekiq'
|
4
|
+
require "ruby_event_store/outbox/sidekiq5_format"
|
5
|
+
|
6
|
+
module RubyEventStore
|
7
|
+
module Outbox
|
8
|
+
class SidekiqProducer
|
9
|
+
def call(klass, args)
|
10
|
+
sidekiq_client = Sidekiq::Client.new(Sidekiq.redis_pool)
|
11
|
+
item = {
|
12
|
+
'class' => klass,
|
13
|
+
'args' => args,
|
14
|
+
}
|
15
|
+
normalized_item = sidekiq_client.__send__(:normalize_item, item)
|
16
|
+
payload = sidekiq_client.__send__(:process_single, normalized_item.fetch('class'), normalized_item)
|
17
|
+
if payload
|
18
|
+
Record.create!(
|
19
|
+
format: SIDEKIQ5_FORMAT,
|
20
|
+
split_key: payload.fetch('queue'),
|
21
|
+
payload: payload.to_json
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,31 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require "ruby_event_store/outbox/sidekiq5_format"
|
3
|
+
require "ruby_event_store/outbox/sidekiq_producer"
|
5
4
|
|
6
5
|
module RubyEventStore
|
7
6
|
module Outbox
|
8
7
|
class SidekiqScheduler
|
8
|
+
def initialize
|
9
|
+
@sidekiq_producer = SidekiqProducer.new
|
10
|
+
end
|
11
|
+
|
9
12
|
def call(klass, serialized_event)
|
10
|
-
|
11
|
-
item = {
|
12
|
-
'class' => klass,
|
13
|
-
'args' => [serialized_event.to_h],
|
14
|
-
}
|
15
|
-
normalized_item = sidekiq_client.__send__(:normalize_item, item)
|
16
|
-
payload = sidekiq_client.__send__(:process_single, normalized_item.fetch('class'), normalized_item)
|
17
|
-
if payload
|
18
|
-
Record.create!(
|
19
|
-
format: SIDEKIQ5_FORMAT,
|
20
|
-
split_key: payload.fetch('queue'),
|
21
|
-
payload: payload.to_json
|
22
|
-
)
|
23
|
-
end
|
13
|
+
sidekiq_producer.call(klass, [serialized_event.to_h])
|
24
14
|
end
|
25
15
|
|
26
16
|
def verify(subscriber)
|
27
17
|
Class === subscriber && subscriber.respond_to?(:through_outbox?) && subscriber.through_outbox?
|
28
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
attr_reader :sidekiq_producer
|
29
22
|
end
|
30
23
|
end
|
31
24
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_event_store-outbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arkency
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby_event_store
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -53,12 +53,16 @@ files:
|
|
53
53
|
- lib/ruby_event_store/outbox.rb
|
54
54
|
- lib/ruby_event_store/outbox/cli.rb
|
55
55
|
- lib/ruby_event_store/outbox/consumer.rb
|
56
|
+
- lib/ruby_event_store/outbox/consumer_process.rb
|
57
|
+
- lib/ruby_event_store/outbox/fetch_specification.rb
|
56
58
|
- lib/ruby_event_store/outbox/metrics.rb
|
57
59
|
- lib/ruby_event_store/outbox/metrics/influx.rb
|
58
60
|
- lib/ruby_event_store/outbox/metrics/null.rb
|
59
61
|
- lib/ruby_event_store/outbox/record.rb
|
60
62
|
- lib/ruby_event_store/outbox/sidekiq5_format.rb
|
61
63
|
- lib/ruby_event_store/outbox/sidekiq_message_handler.rb
|
64
|
+
- lib/ruby_event_store/outbox/sidekiq_processor.rb
|
65
|
+
- lib/ruby_event_store/outbox/sidekiq_producer.rb
|
62
66
|
- lib/ruby_event_store/outbox/sidekiq_scheduler.rb
|
63
67
|
- lib/ruby_event_store/outbox/version.rb
|
64
68
|
homepage: https://railseventstore.org
|