totoro 0.6.1 → 1.0.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 +4 -4
- data/lib/generators/totoro/templates/create_totoro_failed_messages.rb +1 -0
- data/lib/generators/totoro/templates/update_totoro_failed_messages.rb +6 -0
- data/lib/generators/totoro/update_generator.rb +12 -0
- data/lib/totoro/base_queue.rb +11 -35
- data/lib/totoro/base_worker.rb +12 -14
- data/lib/totoro/config.rb +8 -0
- data/lib/totoro/errors/connection_break_error.rb +6 -0
- data/lib/totoro/errors/need_queue_name_error.rb +5 -0
- data/lib/totoro/message_resender.rb +1 -7
- data/lib/totoro/{totoro_failed_message.rb → models/totoro_failed_message.rb} +0 -0
- data/lib/totoro/services/broadcast_service.rb +33 -0
- data/lib/totoro/services/enqueue_service.rb +38 -0
- data/lib/totoro/services/resend_service.rb +17 -0
- data/lib/totoro/services/subscribe_service.rb +31 -0
- data/lib/totoro/version.rb +1 -1
- data/lib/totoro.rb +7 -1
- data/pkg/totoro-0.6.1.gem +0 -0
- data/test/totoro_test/Gemfile.lock +3 -3
- data/test/totoro_test/app/models/worker/exchange_queue.rb +10 -0
- data/test/totoro_test/app/models/worker/shu_queue.rb +10 -0
- data/test/totoro_test/config/totoro.yml +11 -0
- data/test/totoro_test/db/migrate/20181228033422_update_totoro_failed_messages.rb +5 -0
- data/test/totoro_test/db/schema.rb +24 -21
- data/totoro.gemspec +0 -1
- metadata +15 -4
- data/TODO +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46971dbec9f717c43e7cd0886b94b4391374786557286ee0e0854e424999ded6
|
4
|
+
data.tar.gz: 3b512d046ed53091adc36a4809e128d8d436a24e0e49b2ad1086031b45ae7b41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61e5a11bb89c80a98d46ee66ba20c6410da252fb3c5030d65ef3b944719ffa3feee561f0227a2e4cf953cea8b5c70a0d826de0655d95e0e81ea5a5840e0f7c61
|
7
|
+
data.tar.gz: 5a77beb59c2f8521c3b42738d212ef66c76b14d62fb4f04782684b9ad6c62761f55be4edad078e4e701119c9e4eea9378ba416d1a91147fdc72494a6d07a5f0d
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Totoro
|
4
|
+
class UpdateGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
desc 'Update totoro to 1.0.0'
|
7
|
+
|
8
|
+
def copy_config_file
|
9
|
+
template 'update_totoro_failed_messages.rb', File.join('db/migrate', "#{Time.now.strftime('%Y%m%d%H%M%S')}_update_totoro_failed_messages.rb")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/totoro/base_queue.rb
CHANGED
@@ -10,59 +10,35 @@ module Totoro
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def connection
|
13
|
-
@connection ||= Bunny.new(config.connect.merge(threaded: false))
|
13
|
+
@connection ||= Bunny.new(config.connect.merge(threaded: false))
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def broadcast(id, payload)
|
17
|
+
Totoro::BroadcastService.new(connection, config).broadcast(id, payload)
|
18
|
+
rescue Totoro::ConnectionBreakError => error
|
19
|
+
handle_failed_msg(id, payload, error, :broadcast)
|
18
20
|
end
|
19
21
|
|
20
22
|
def enqueue(id, payload)
|
21
|
-
|
22
|
-
|
23
|
-
payload
|
24
|
-
channel.default_exchange.publish(payload, routing_key: queue.name)
|
25
|
-
Rails.logger.info "send message to #{queue.name}"
|
26
|
-
STDOUT.flush
|
27
|
-
channel.close
|
28
|
-
rescue Bunny::TCPConnectionFailedForAllHosts,
|
29
|
-
Bunny::NetworkErrorWrapper,
|
30
|
-
Bunny::ChannelAlreadyClosed,
|
31
|
-
AMQ::Protocol::EmptyResponseError => error
|
32
|
-
handle_failed_msg(id, payload, error)
|
33
|
-
end
|
34
|
-
|
35
|
-
def subscribe(id)
|
36
|
-
queue = subscribe_channel.queue(*config.queue(id))
|
37
|
-
queue.subscribe do |delivery_info, metadata, payload|
|
38
|
-
yield(delivery_info, metadata, payload)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def get_worker(worker_class)
|
43
|
-
::Worker.const_get(worker_class.to_s.camelize).new
|
23
|
+
Totoro::EnqueueService.new(connection, config).enqueue(id, payload)
|
24
|
+
rescue Totoro::ConnectionBreakError => error
|
25
|
+
handle_failed_msg(id, payload, error, :enqueue)
|
44
26
|
end
|
45
27
|
|
46
28
|
private
|
47
29
|
|
48
|
-
def handle_failed_msg(id, payload, error)
|
30
|
+
def handle_failed_msg(id, payload, error, group)
|
49
31
|
Rails.logger.error error.message
|
50
32
|
Rails.logger.info 'Add failed message to resend list'
|
51
33
|
STDOUT.flush
|
52
|
-
|
34
|
+
@connection = nil
|
53
35
|
Totoro::TotoroFailedMessage.create(
|
54
36
|
class_name: to_s,
|
55
37
|
queue_id: id,
|
38
|
+
group: group,
|
56
39
|
payload: payload
|
57
40
|
)
|
58
41
|
end
|
59
|
-
|
60
|
-
def clear_connection
|
61
|
-
@exchange = nil
|
62
|
-
@channel = nil
|
63
|
-
@subscribe_channel = nil
|
64
|
-
@connection = nil
|
65
|
-
end
|
66
42
|
end
|
67
43
|
end
|
68
44
|
end
|
data/lib/totoro/base_worker.rb
CHANGED
@@ -7,6 +7,7 @@ module Totoro
|
|
7
7
|
queue_name = attrs[:queue_name]
|
8
8
|
define_method('setup') do
|
9
9
|
raise(Totoro::NeedQueueNameError) if queue_name.nil?
|
10
|
+
|
10
11
|
@prefix = prefix
|
11
12
|
@queue_name = queue_name
|
12
13
|
end
|
@@ -14,22 +15,21 @@ module Totoro
|
|
14
15
|
|
15
16
|
def initialize
|
16
17
|
setup
|
17
|
-
@queue_class = queue_class
|
18
18
|
end
|
19
19
|
|
20
20
|
def execute
|
21
|
-
|
21
|
+
Rails.logger.info 'Listening to the Rabbitmq'
|
22
|
+
STDOUT.flush
|
23
|
+
subscribe_service.subscribe(@queue_name) do |delivery_info, metadata, payload|
|
22
24
|
Rails.logger.info "#{@queue_name} received message"
|
23
25
|
STDOUT.flush
|
24
26
|
payload_hash = JSON.parse(payload).with_indifferent_access
|
25
27
|
process(payload_hash, metadata, delivery_info)
|
26
28
|
end
|
27
|
-
|
28
|
-
STDOUT.flush
|
29
|
-
@queue_class.subscribe_channel.work_pool.join
|
29
|
+
subscribe_service.channel.work_pool.join
|
30
30
|
rescue SignalException
|
31
31
|
puts 'Terminating process ..'
|
32
|
-
|
32
|
+
subscribe_service.channel.work_pool.shutdown(true)
|
33
33
|
puts 'Stopped.'
|
34
34
|
end
|
35
35
|
|
@@ -37,14 +37,12 @@ module Totoro
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
def
|
41
|
-
|
42
|
-
Totoro::Queue
|
43
|
-
else
|
44
|
-
"Totoro::#{@prefix.to_s.camelize}::Queue".constantize
|
45
|
-
end
|
40
|
+
def config
|
41
|
+
@config ||= Totoro::Config.new(@prefix)
|
46
42
|
end
|
47
|
-
end
|
48
43
|
|
49
|
-
|
44
|
+
def subscribe_service
|
45
|
+
@subscribe_service ||= Totoro::SubscribeService.new(config)
|
46
|
+
end
|
47
|
+
end
|
50
48
|
end
|
data/lib/totoro/config.rb
CHANGED
@@ -15,6 +15,14 @@ module Totoro
|
|
15
15
|
@data[:connect]
|
16
16
|
end
|
17
17
|
|
18
|
+
def exchange(id)
|
19
|
+
@data[:exchange][id][:name]
|
20
|
+
end
|
21
|
+
|
22
|
+
def exchange_name_for_queue(queue_id)
|
23
|
+
@data[:queue][queue_id][:exchange]
|
24
|
+
end
|
25
|
+
|
18
26
|
def queue(id)
|
19
27
|
name = @data[:queue][id][:name]
|
20
28
|
settings = { durable: @data[:queue][id][:durable] }
|
@@ -8,13 +8,7 @@ module Totoro
|
|
8
8
|
run_every 10.second
|
9
9
|
queue 'totoro'
|
10
10
|
def perform
|
11
|
-
Totoro::
|
12
|
-
Totoro::TotoroFailedMessage.find_in_batches(batch_size: 100) do |message_group|
|
13
|
-
message_group.each do |m|
|
14
|
-
m.class_name.constantize.enqueue(m.queue_id, m.payload)
|
15
|
-
m.destroy
|
16
|
-
end
|
17
|
-
end
|
11
|
+
Totoro::ResendService.new.resend_all_messages
|
18
12
|
rescue StandardError => error
|
19
13
|
Rails.logger.error error.message
|
20
14
|
STDOUT.flush
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Totoro
|
4
|
+
class BroadcastService
|
5
|
+
def initialize(connection, config)
|
6
|
+
@connection = connection
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def broadcast(exchange_id, payload)
|
11
|
+
@connection.start unless @connection.connected?
|
12
|
+
exchange = channel.fanout(@config.exchange(exchange_id))
|
13
|
+
payload = JSON.dump payload
|
14
|
+
exchange.publish(payload)
|
15
|
+
Rails.logger.info "send message to exchange #{@config.exchange(exchange_id)}"
|
16
|
+
STDOUT.flush
|
17
|
+
channel.close
|
18
|
+
rescue Bunny::TCPConnectionFailedForAllHosts,
|
19
|
+
Bunny::NetworkErrorWrapper,
|
20
|
+
Bunny::ChannelAlreadyClosed,
|
21
|
+
Bunny::ConnectionAlreadyClosed,
|
22
|
+
AMQ::Protocol::EmptyResponseError => error
|
23
|
+
@channel.close if @channel.present?
|
24
|
+
raise(Totoro::ConnectionBreakError, "type: #{error.class}, message: #{error.message}")
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def channel
|
30
|
+
@channel ||= @connection.create_channel
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Totoro
|
4
|
+
class EnqueueService
|
5
|
+
def initialize(connection, config)
|
6
|
+
@connection = connection
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def enqueue(id, payload)
|
11
|
+
@connection.start unless @connection.connected?
|
12
|
+
queue = channel.queue(*@config.queue(id))
|
13
|
+
payload = JSON.dump payload
|
14
|
+
exchange.publish(payload, routing_key: queue.name)
|
15
|
+
Rails.logger.info "send message to #{queue.name}"
|
16
|
+
STDOUT.flush
|
17
|
+
channel.close
|
18
|
+
rescue Bunny::TCPConnectionFailedForAllHosts,
|
19
|
+
Bunny::NetworkErrorWrapper,
|
20
|
+
Bunny::ChannelAlreadyClosed,
|
21
|
+
Bunny::ConnectionAlreadyClosed,
|
22
|
+
AMQ::Protocol::EmptyResponseError => error
|
23
|
+
@channel.close if @channel.present?
|
24
|
+
raise(Totoro::ConnectionBreakError, "type: #{error.class}, message: #{error.message}")
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def channel
|
30
|
+
@channel ||= @connection.create_channel
|
31
|
+
end
|
32
|
+
|
33
|
+
# default exchange is a direct exchange
|
34
|
+
def exchange
|
35
|
+
@exchange ||= channel.default_exchange
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Totoro
|
2
|
+
class ResendService
|
3
|
+
def resend_all_messages
|
4
|
+
Totoro::TotoroFailedMessage.find_in_batches(batch_size: 100) do |message_group|
|
5
|
+
message_group.each { |m| resend_message(m) }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def resend_message(failed_message)
|
12
|
+
queue_class = failed_message.class_name.constantize
|
13
|
+
queue_class.method(failed_message.group).call(failed_message.queue_id, failed_message.payload)
|
14
|
+
failed_message.destroy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Totoro
|
4
|
+
class SubscribeService
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def subscribe(id)
|
10
|
+
queue = bind_queue(id)
|
11
|
+
queue.subscribe do |delivery_info, metadata, payload|
|
12
|
+
yield(delivery_info, metadata, payload)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def channel
|
17
|
+
@channel ||= Bunny.new(@config.connect).tap(&:start).create_channel
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def bind_queue(id)
|
23
|
+
exchange_name = @config.exchange_name_for_queue(id)
|
24
|
+
if exchange_name.nil?
|
25
|
+
channel.queue(*@config.queue(id))
|
26
|
+
else
|
27
|
+
channel.queue(*@config.queue(id)).bind(exchange_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/totoro/version.rb
CHANGED
data/lib/totoro.rb
CHANGED
@@ -4,9 +4,15 @@ require 'totoro/version'
|
|
4
4
|
require 'totoro/config'
|
5
5
|
require 'totoro/base_queue'
|
6
6
|
require 'totoro/base_worker'
|
7
|
+
require 'totoro/services/enqueue_service'
|
8
|
+
require 'totoro/services/broadcast_service'
|
9
|
+
require 'totoro/services/subscribe_service'
|
10
|
+
require 'totoro/services/resend_service'
|
11
|
+
require 'totoro/errors/connection_break_error'
|
12
|
+
require 'totoro/errors/need_queue_name_error'
|
7
13
|
require 'totoro/initializer'
|
8
14
|
require 'totoro/message_resender'
|
9
|
-
require 'totoro/totoro_failed_message'
|
15
|
+
require 'totoro/models/totoro_failed_message'
|
10
16
|
require 'totoro/railtie' if defined?(Rails)
|
11
17
|
|
12
18
|
module Totoro
|
Binary file
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: /totoro
|
3
3
|
specs:
|
4
|
-
totoro (0.6.
|
4
|
+
totoro (0.6.1)
|
5
5
|
bunny (~> 2.10)
|
6
6
|
delayed_job_active_record (~> 4.1.3)
|
7
7
|
delayed_job_recurring (~> 0.3.7)
|
@@ -49,8 +49,8 @@ GEM
|
|
49
49
|
amq-protocol (2.3.0)
|
50
50
|
arel (8.0.0)
|
51
51
|
builder (3.2.3)
|
52
|
-
bunny (2.
|
53
|
-
amq-protocol (~> 2.3.0)
|
52
|
+
bunny (2.13.0)
|
53
|
+
amq-protocol (~> 2.3, >= 2.3.0)
|
54
54
|
byebug (10.0.2)
|
55
55
|
concurrent-ruby (1.0.5)
|
56
56
|
crass (1.0.4)
|
@@ -9,6 +9,17 @@ default: &default
|
|
9
9
|
example_queue:
|
10
10
|
name: real.queue.name
|
11
11
|
durable: true
|
12
|
+
exchange_queue:
|
13
|
+
name: real.exchange.queue
|
14
|
+
durable: true
|
15
|
+
exchange: real.exchange.name
|
16
|
+
shu_queue:
|
17
|
+
name: real.shu.queue
|
18
|
+
durable: true
|
19
|
+
exchange: real.exchange.name
|
20
|
+
exchange:
|
21
|
+
example_exchange:
|
22
|
+
name: real.exchange.name
|
12
23
|
|
13
24
|
custom:
|
14
25
|
connect:
|
@@ -10,30 +10,33 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 20181228033422) do
|
14
|
+
|
14
15
|
# These are extensions that must be enabled in order to support this database
|
15
|
-
enable_extension
|
16
|
+
enable_extension "plpgsql"
|
16
17
|
|
17
|
-
create_table
|
18
|
-
t.integer
|
19
|
-
t.integer
|
20
|
-
t.text
|
21
|
-
t.text
|
22
|
-
t.datetime
|
23
|
-
t.datetime
|
24
|
-
t.datetime
|
25
|
-
t.string
|
26
|
-
t.string
|
27
|
-
t.datetime
|
28
|
-
t.datetime
|
29
|
-
t.index
|
18
|
+
create_table "delayed_jobs", force: :cascade do |t|
|
19
|
+
t.integer "priority", default: 0, null: false
|
20
|
+
t.integer "attempts", default: 0, null: false
|
21
|
+
t.text "handler", null: false
|
22
|
+
t.text "last_error"
|
23
|
+
t.datetime "run_at"
|
24
|
+
t.datetime "locked_at"
|
25
|
+
t.datetime "failed_at"
|
26
|
+
t.string "locked_by"
|
27
|
+
t.string "queue"
|
28
|
+
t.datetime "created_at"
|
29
|
+
t.datetime "updated_at"
|
30
|
+
t.index ["priority", "run_at"], name: "delayed_jobs_priority"
|
30
31
|
end
|
31
32
|
|
32
|
-
create_table
|
33
|
-
t.string
|
34
|
-
t.string
|
35
|
-
t.jsonb
|
36
|
-
t.datetime
|
37
|
-
t.datetime
|
33
|
+
create_table "totoro_failed_messages", force: :cascade do |t|
|
34
|
+
t.string "class_name"
|
35
|
+
t.string "queue_id"
|
36
|
+
t.jsonb "payload"
|
37
|
+
t.datetime "created_at", null: false
|
38
|
+
t.datetime "updated_at", null: false
|
39
|
+
t.string "group"
|
38
40
|
end
|
41
|
+
|
39
42
|
end
|
data/totoro.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: totoro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ShuHui18
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -109,7 +109,6 @@ files:
|
|
109
109
|
- LICENSE.txt
|
110
110
|
- README.md
|
111
111
|
- Rakefile
|
112
|
-
- TODO
|
113
112
|
- bin/console
|
114
113
|
- bin/setup
|
115
114
|
- bin/totoro
|
@@ -119,19 +118,28 @@ files:
|
|
119
118
|
- lib/generators/totoro/templates/create_totoro_failed_messages.rb
|
120
119
|
- lib/generators/totoro/templates/initializer.rb
|
121
120
|
- lib/generators/totoro/templates/totoro.yml
|
121
|
+
- lib/generators/totoro/templates/update_totoro_failed_messages.rb
|
122
122
|
- lib/generators/totoro/templates/worker.rb.erb
|
123
|
+
- lib/generators/totoro/update_generator.rb
|
123
124
|
- lib/generators/totoro/worker_generator.rb
|
124
125
|
- lib/totoro.rb
|
125
126
|
- lib/totoro/base_queue.rb
|
126
127
|
- lib/totoro/base_worker.rb
|
127
128
|
- lib/totoro/config.rb
|
129
|
+
- lib/totoro/errors/connection_break_error.rb
|
130
|
+
- lib/totoro/errors/need_queue_name_error.rb
|
128
131
|
- lib/totoro/initializer.rb
|
129
132
|
- lib/totoro/message_resender.rb
|
133
|
+
- lib/totoro/models/totoro_failed_message.rb
|
130
134
|
- lib/totoro/railtie.rb
|
135
|
+
- lib/totoro/services/broadcast_service.rb
|
136
|
+
- lib/totoro/services/enqueue_service.rb
|
137
|
+
- lib/totoro/services/resend_service.rb
|
138
|
+
- lib/totoro/services/subscribe_service.rb
|
131
139
|
- lib/totoro/tasks/resend_message.rake
|
132
|
-
- lib/totoro/totoro_failed_message.rb
|
133
140
|
- lib/totoro/version.rb
|
134
141
|
- pkg/totoro-0.6.0.gem
|
142
|
+
- pkg/totoro-0.6.1.gem
|
135
143
|
- spec/spec_helper.rb
|
136
144
|
- spec/totoro_spec.rb
|
137
145
|
- test/rabbitmq_commands.txt
|
@@ -146,6 +154,8 @@ files:
|
|
146
154
|
- test/totoro_test/app/mailers/application_mailer.rb
|
147
155
|
- test/totoro_test/app/models/application_record.rb
|
148
156
|
- test/totoro_test/app/models/worker/example_queue.rb
|
157
|
+
- test/totoro_test/app/models/worker/exchange_queue.rb
|
158
|
+
- test/totoro_test/app/models/worker/shu_queue.rb
|
149
159
|
- test/totoro_test/app/services/bench_mark.txt
|
150
160
|
- test/totoro_test/app/services/load_test.rb
|
151
161
|
- test/totoro_test/app/views/layouts/mailer.html.erb
|
@@ -183,6 +193,7 @@ files:
|
|
183
193
|
- test/totoro_test/db/development.sqlite3
|
184
194
|
- test/totoro_test/db/migrate/20181019041208_create_delayed_jobs.rb
|
185
195
|
- test/totoro_test/db/migrate/20181019070846_create_totoro_failed_messages.rb
|
196
|
+
- test/totoro_test/db/migrate/20181228033422_update_totoro_failed_messages.rb
|
186
197
|
- test/totoro_test/db/schema.rb
|
187
198
|
- test/totoro_test/db/seeds.rb
|
188
199
|
- test/totoro_test/db/test.sqlite3
|