identity_cache 0.4.1 → 1.1.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 +5 -5
- data/.github/probots.yml +2 -0
- data/.github/workflows/ci.yml +92 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +5 -0
- data/CAVEATS.md +25 -0
- data/CHANGELOG.md +73 -19
- data/Gemfile +5 -1
- data/LICENSE +1 -1
- data/README.md +49 -27
- data/Rakefile +14 -5
- data/dev.yml +12 -16
- data/gemfiles/Gemfile.latest-release +8 -0
- data/gemfiles/Gemfile.min-supported +7 -0
- data/gemfiles/Gemfile.rails-edge +7 -0
- data/identity_cache.gemspec +29 -10
- data/lib/identity_cache.rb +78 -51
- data/lib/identity_cache/belongs_to_caching.rb +12 -40
- data/lib/identity_cache/cache_fetcher.rb +6 -5
- data/lib/identity_cache/cache_hash.rb +2 -2
- data/lib/identity_cache/cache_invalidation.rb +4 -11
- data/lib/identity_cache/cache_key_generation.rb +17 -65
- data/lib/identity_cache/cache_key_loader.rb +128 -0
- data/lib/identity_cache/cached.rb +7 -0
- data/lib/identity_cache/cached/association.rb +87 -0
- data/lib/identity_cache/cached/attribute.rb +123 -0
- data/lib/identity_cache/cached/attribute_by_multi.rb +37 -0
- data/lib/identity_cache/cached/attribute_by_one.rb +88 -0
- data/lib/identity_cache/cached/belongs_to.rb +100 -0
- data/lib/identity_cache/cached/embedded_fetching.rb +41 -0
- data/lib/identity_cache/cached/prefetcher.rb +61 -0
- data/lib/identity_cache/cached/primary_index.rb +96 -0
- data/lib/identity_cache/cached/recursive/association.rb +109 -0
- data/lib/identity_cache/cached/recursive/has_many.rb +9 -0
- data/lib/identity_cache/cached/recursive/has_one.rb +9 -0
- data/lib/identity_cache/cached/reference/association.rb +16 -0
- data/lib/identity_cache/cached/reference/has_many.rb +105 -0
- data/lib/identity_cache/cached/reference/has_one.rb +100 -0
- data/lib/identity_cache/configuration_dsl.rb +53 -215
- data/lib/identity_cache/encoder.rb +95 -0
- data/lib/identity_cache/expiry_hook.rb +36 -0
- data/lib/identity_cache/fallback_fetcher.rb +2 -1
- data/lib/identity_cache/load_strategy/eager.rb +28 -0
- data/lib/identity_cache/load_strategy/lazy.rb +71 -0
- data/lib/identity_cache/load_strategy/load_request.rb +20 -0
- data/lib/identity_cache/load_strategy/multi_load_request.rb +27 -0
- data/lib/identity_cache/mem_cache_store_cas.rb +53 -0
- data/lib/identity_cache/memoized_cache_proxy.rb +137 -58
- data/lib/identity_cache/parent_model_expiration.rb +46 -11
- data/lib/identity_cache/query_api.rb +102 -408
- data/lib/identity_cache/railtie.rb +8 -0
- data/lib/identity_cache/record_not_found.rb +6 -0
- data/lib/identity_cache/should_use_cache.rb +1 -0
- data/lib/identity_cache/version.rb +3 -2
- data/lib/identity_cache/with_primary_index.rb +136 -0
- data/lib/identity_cache/without_primary_index.rb +24 -3
- data/performance/cache_runner.rb +25 -73
- data/performance/cpu.rb +4 -3
- data/performance/externals.rb +4 -3
- data/performance/profile.rb +6 -5
- data/railgun.yml +16 -0
- metadata +60 -73
- data/.travis.yml +0 -30
- data/Gemfile.rails42 +0 -6
- data/Gemfile.rails50 +0 -6
- data/test/attribute_cache_test.rb +0 -110
- data/test/cache_fetch_includes_test.rb +0 -46
- data/test/cache_hash_test.rb +0 -14
- data/test/cache_invalidation_test.rb +0 -139
- data/test/deeply_nested_associated_record_test.rb +0 -19
- data/test/denormalized_has_many_test.rb +0 -211
- data/test/denormalized_has_one_test.rb +0 -160
- data/test/fetch_multi_test.rb +0 -308
- data/test/fetch_test.rb +0 -258
- data/test/fixtures/serialized_record.mysql2 +0 -0
- data/test/fixtures/serialized_record.postgresql +0 -0
- data/test/helpers/active_record_objects.rb +0 -106
- data/test/helpers/database_connection.rb +0 -72
- data/test/helpers/serialization_format.rb +0 -42
- data/test/helpers/update_serialization_format.rb +0 -24
- data/test/identity_cache_test.rb +0 -29
- data/test/index_cache_test.rb +0 -161
- data/test/memoized_attributes_test.rb +0 -49
- data/test/memoized_cache_proxy_test.rb +0 -107
- data/test/normalized_belongs_to_test.rb +0 -107
- data/test/normalized_has_many_test.rb +0 -231
- data/test/normalized_has_one_test.rb +0 -9
- data/test/prefetch_associations_test.rb +0 -364
- data/test/readonly_test.rb +0 -109
- data/test/recursive_denormalized_has_many_test.rb +0 -131
- data/test/save_test.rb +0 -82
- data/test/schema_change_test.rb +0 -112
- data/test/serialization_format_change_test.rb +0 -16
- data/test/test_helper.rb +0 -140
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module IdentityCache
|
3
|
+
module WithPrimaryIndex
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
include WithoutPrimaryIndex
|
7
|
+
|
8
|
+
def expire_cache
|
9
|
+
expire_primary_index
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
def expire_primary_index # :nodoc:
|
15
|
+
self.class.expire_primary_key_cache_index(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
def primary_cache_index_key # :nodoc:
|
20
|
+
self.class.cached_primary_index.cache_key(id)
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
# @api private
|
25
|
+
def cached_primary_index
|
26
|
+
@cached_primary_index ||= Cached::PrimaryIndex.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_cache_index_enabled
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
# Declares a new index in the cache for the class where IdentityCache was
|
34
|
+
# included.
|
35
|
+
#
|
36
|
+
# IdentityCache will add a fetch_by_field1_and_field2_and_...field for every
|
37
|
+
# index.
|
38
|
+
#
|
39
|
+
# == Example:
|
40
|
+
#
|
41
|
+
# class Product
|
42
|
+
# include IdentityCache
|
43
|
+
# cache_index :name, :vendor
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# Will add Product.fetch_by_name_and_vendor
|
47
|
+
#
|
48
|
+
# == Parameters
|
49
|
+
#
|
50
|
+
# +fields+ Array of symbols or strings representing the fields in the index
|
51
|
+
#
|
52
|
+
# == Options
|
53
|
+
# * unique: if the index would only have unique values. Default is false
|
54
|
+
#
|
55
|
+
def cache_index(*fields, unique: false)
|
56
|
+
attribute_proc = -> { primary_key }
|
57
|
+
cache_attribute_by_alias(attribute_proc, alias_name: :id, by: fields, unique: unique)
|
58
|
+
|
59
|
+
field_list = fields.join("_and_")
|
60
|
+
arg_list = (0...fields.size).collect { |i| "arg#{i}" }.join(',')
|
61
|
+
|
62
|
+
if unique
|
63
|
+
instance_eval(<<-CODE, __FILE__, __LINE__ + 1)
|
64
|
+
def fetch_by_#{field_list}(#{arg_list}, includes: nil)
|
65
|
+
id = fetch_id_by_#{field_list}(#{arg_list})
|
66
|
+
id && fetch_by_id(id, includes: includes)
|
67
|
+
end
|
68
|
+
|
69
|
+
# exception throwing variant
|
70
|
+
def fetch_by_#{field_list}!(#{arg_list}, includes: nil)
|
71
|
+
fetch_by_#{field_list}(#{arg_list}, includes: includes) or raise IdentityCache::RecordNotFound
|
72
|
+
end
|
73
|
+
CODE
|
74
|
+
else
|
75
|
+
instance_eval(<<-CODE, __FILE__, __LINE__ + 1)
|
76
|
+
def fetch_by_#{field_list}(#{arg_list}, includes: nil)
|
77
|
+
ids = fetch_id_by_#{field_list}(#{arg_list})
|
78
|
+
ids.empty? ? ids : fetch_multi(ids, includes: includes)
|
79
|
+
end
|
80
|
+
CODE
|
81
|
+
end
|
82
|
+
|
83
|
+
if fields.length == 1
|
84
|
+
instance_eval(<<-CODE, __FILE__, __LINE__ + 1)
|
85
|
+
def fetch_multi_by_#{field_list}(index_values, includes: nil)
|
86
|
+
ids = fetch_multi_id_by_#{field_list}(index_values).values.flatten(1)
|
87
|
+
return ids if ids.empty?
|
88
|
+
fetch_multi(ids, includes: includes)
|
89
|
+
end
|
90
|
+
CODE
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Similar to ActiveRecord::Base#exists? will return true if the id can be
|
95
|
+
# found in the cache or in the DB.
|
96
|
+
def exists_with_identity_cache?(id)
|
97
|
+
!!fetch_by_id(id)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Default fetcher added to the model on inclusion, it behaves like
|
101
|
+
# ActiveRecord::Base.where(id: id).first
|
102
|
+
def fetch_by_id(id, includes: nil)
|
103
|
+
ensure_base_model
|
104
|
+
raise_if_scoped
|
105
|
+
record = cached_primary_index.fetch(id)
|
106
|
+
prefetch_associations(includes, [record]) if record && includes
|
107
|
+
record
|
108
|
+
end
|
109
|
+
|
110
|
+
# Default fetcher added to the model on inclusion, it behaves like
|
111
|
+
# ActiveRecord::Base.find, but will raise IdentityCache::RecordNotFound
|
112
|
+
# if the id is not in the cache.
|
113
|
+
def fetch(id, includes: nil)
|
114
|
+
fetch_by_id(id, includes: includes) || raise(
|
115
|
+
IdentityCache::RecordNotFound, "Couldn't find #{name} with ID=#{id}"
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Default fetcher added to the model on inclusion, if behaves like
|
120
|
+
# ActiveRecord::Base.find_all_by_id
|
121
|
+
def fetch_multi(*ids, includes: nil)
|
122
|
+
ensure_base_model
|
123
|
+
raise_if_scoped
|
124
|
+
ids.flatten!(1)
|
125
|
+
records = cached_primary_index.fetch_multi(ids)
|
126
|
+
prefetch_associations(includes, records) if includes
|
127
|
+
records
|
128
|
+
end
|
129
|
+
|
130
|
+
# Invalidates the primary cache index for the associated record. Will not invalidate cached attributes.
|
131
|
+
def expire_primary_key_cache_index(id)
|
132
|
+
cached_primary_index.expire(id)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -1,10 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module IdentityCache
|
2
3
|
module WithoutPrimaryIndex
|
3
4
|
extend ActiveSupport::Concern
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
include ArTransactionChanges
|
7
|
+
include IdentityCache::BelongsToCaching
|
8
|
+
include IdentityCache::CacheKeyGeneration
|
9
|
+
include IdentityCache::ConfigurationDSL
|
10
|
+
include IdentityCache::QueryAPI
|
11
|
+
include IdentityCache::CacheInvalidation
|
12
|
+
include IdentityCache::ShouldUseCache
|
13
|
+
include ParentModelExpiration
|
14
|
+
|
15
|
+
def self.append_features(base) #:nodoc:
|
16
|
+
raise AlreadyIncludedError if base.include?(WithoutPrimaryIndex)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
included do
|
21
|
+
class_attribute(:cached_model)
|
22
|
+
self.cached_model = self
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
def primary_cache_index_enabled
|
27
|
+
false
|
28
|
+
end
|
8
29
|
end
|
9
30
|
end
|
10
31
|
end
|
data/performance/cache_runner.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
|
2
3
|
require 'active_record'
|
3
4
|
require 'active_support/core_ext'
|
4
5
|
require 'active_support/cache'
|
@@ -6,25 +7,19 @@ require 'identity_cache'
|
|
6
7
|
require 'memcached_store'
|
7
8
|
require 'active_support/cache/memcached_store'
|
8
9
|
|
9
|
-
$memcached_port = 11211
|
10
|
-
$mysql_port = 3306
|
11
|
-
|
12
10
|
require File.dirname(__FILE__) + '/../test/helpers/active_record_objects'
|
13
11
|
require File.dirname(__FILE__) + '/../test/helpers/database_connection'
|
12
|
+
require File.dirname(__FILE__) + '/../test/helpers/cache_connection'
|
14
13
|
|
15
14
|
IdentityCache.logger = Logger.new(nil)
|
16
|
-
|
17
|
-
|
18
|
-
if ActiveRecord.gem_version < Gem::Version.new('5') && ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks=)
|
19
|
-
ActiveRecord::Base.raise_in_transactional_callbacks = true
|
20
|
-
end
|
15
|
+
CacheConnection.setup
|
21
16
|
|
22
17
|
def create_record(id)
|
23
18
|
Item.new(id)
|
24
19
|
end
|
25
20
|
|
26
21
|
def database_ready(count)
|
27
|
-
Item.where(:
|
22
|
+
Item.where(id: (1..count)).count == count
|
28
23
|
rescue
|
29
24
|
false
|
30
25
|
end
|
@@ -42,26 +37,25 @@ def create_database(count)
|
|
42
37
|
DatabaseConnection.create_tables
|
43
38
|
existing = Item.all
|
44
39
|
(1..count).to_a.each do |i|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
a.save
|
40
|
+
next if existing.any? { |e| e.id == i }
|
41
|
+
a = Item.new
|
42
|
+
a.id = i
|
43
|
+
a.associated = AssociatedRecord.new(name: "Associated for #{i}")
|
44
|
+
a.associated_records
|
45
|
+
(1..5).each do |j|
|
46
|
+
a.associated_records << AssociatedRecord.new(name: "Has Many #{j} for #{i}")
|
47
|
+
a.normalized_associated_records << NormalizedAssociatedRecord.new(name: "Normalized Has Many #{j} for #{i}")
|
55
48
|
end
|
49
|
+
a.save
|
56
50
|
end
|
57
51
|
ensure
|
58
52
|
helper.teardown_models
|
59
53
|
end
|
60
54
|
|
61
55
|
def setup_embedded_associations
|
62
|
-
Item.cache_has_one :
|
63
|
-
Item.cache_has_many
|
64
|
-
AssociatedRecord.cache_has_many
|
56
|
+
Item.cache_has_one(:associated, embed: true)
|
57
|
+
Item.cache_has_many(:associated_records, embed: true)
|
58
|
+
AssociatedRecord.cache_has_many(:deeply_associated_records, embed: true)
|
65
59
|
end
|
66
60
|
|
67
61
|
class CacheRunner
|
@@ -86,7 +80,7 @@ CACHE_RUNNERS = []
|
|
86
80
|
class FindRunner < CacheRunner
|
87
81
|
def run
|
88
82
|
(1..@count).each do |i|
|
89
|
-
::Item.includes(:associated,
|
83
|
+
::Item.includes(:associated, associated_records: :deeply_associated_records).find(i)
|
90
84
|
end
|
91
85
|
end
|
92
86
|
end
|
@@ -109,38 +103,16 @@ end
|
|
109
103
|
module DeletedRunner
|
110
104
|
def prepare
|
111
105
|
super
|
112
|
-
(1..@count).each {|i| ::Item.find(i).
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
module ConflictRunner
|
117
|
-
def prepare
|
118
|
-
super
|
119
|
-
records = (1..@count).map {|id| ::Item.find(id) }
|
120
|
-
orig_resolve_cache_miss = ::Item.method(:resolve_cache_miss)
|
121
|
-
|
122
|
-
::Item.define_singleton_method(:resolve_cache_miss) do |id|
|
123
|
-
records[id-1].send(:expire_cache)
|
124
|
-
orig_resolve_cache_miss.call(id)
|
125
|
-
end
|
126
|
-
IdentityCache.cache.clear
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
module DeletedConflictRunner
|
131
|
-
include ConflictRunner
|
132
|
-
def prepare
|
133
|
-
super
|
134
|
-
(1..@count).each {|i| ::Item.find(i).send(:expire_cache) }
|
106
|
+
(1..@count).each { |i| ::Item.find(i).expire_cache }
|
135
107
|
end
|
136
108
|
end
|
137
109
|
|
138
110
|
class EmbedRunner < CacheRunner
|
139
111
|
def setup_models
|
140
112
|
super
|
141
|
-
Item.cache_has_one :
|
142
|
-
Item.cache_has_many
|
143
|
-
AssociatedRecord.cache_has_many
|
113
|
+
Item.cache_has_one(:associated, embed: true)
|
114
|
+
Item.cache_has_many(:associated_records, embed: true)
|
115
|
+
AssociatedRecord.cache_has_many(:deeply_associated_records, embed: true)
|
144
116
|
end
|
145
117
|
|
146
118
|
def run
|
@@ -167,22 +139,12 @@ class FetchEmbedDeletedRunner < EmbedRunner
|
|
167
139
|
end
|
168
140
|
CACHE_RUNNERS << FetchEmbedDeletedRunner
|
169
141
|
|
170
|
-
class FetchEmbedConflictRunner < EmbedRunner
|
171
|
-
include ConflictRunner
|
172
|
-
end
|
173
|
-
CACHE_RUNNERS << FetchEmbedConflictRunner
|
174
|
-
|
175
|
-
class FetchEmbedDeletedConflictRunner < EmbedRunner
|
176
|
-
include DeletedConflictRunner
|
177
|
-
end
|
178
|
-
CACHE_RUNNERS << FetchEmbedDeletedConflictRunner
|
179
|
-
|
180
142
|
class NormalizedRunner < CacheRunner
|
181
143
|
def setup_models
|
182
144
|
super
|
183
|
-
Item.cache_has_one
|
184
|
-
Item.cache_has_many
|
185
|
-
AssociatedRecord.cache_has_many
|
145
|
+
Item.cache_has_one(:associated, embed: :id)
|
146
|
+
Item.cache_has_many(:associated_records, embed: :ids)
|
147
|
+
AssociatedRecord.cache_has_many(:deeply_associated_records, embed: :ids)
|
186
148
|
end
|
187
149
|
|
188
150
|
def run
|
@@ -210,13 +172,3 @@ class FetchNormalizedDeletedRunner < NormalizedRunner
|
|
210
172
|
include DeletedRunner
|
211
173
|
end
|
212
174
|
CACHE_RUNNERS << FetchNormalizedDeletedRunner
|
213
|
-
|
214
|
-
class FetchNormalizedConflictRunner < EmbedRunner
|
215
|
-
include ConflictRunner
|
216
|
-
end
|
217
|
-
CACHE_RUNNERS << FetchNormalizedConflictRunner
|
218
|
-
|
219
|
-
class FetchNormalizedDeletedConflictRunner < EmbedRunner
|
220
|
-
include DeletedConflictRunner
|
221
|
-
end
|
222
|
-
CACHE_RUNNERS << FetchNormalizedDeletedConflictRunner
|
data/performance/cpu.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rubygems'
|
2
3
|
require 'benchmark'
|
3
4
|
|
@@ -19,16 +20,16 @@ ensure
|
|
19
20
|
obj.cleanup
|
20
21
|
end
|
21
22
|
|
22
|
-
def benchmark(runners, label_width=0)
|
23
|
+
def benchmark(runners, label_width = 0)
|
23
24
|
IdentityCache.cache.clear
|
24
25
|
runners.each do |runner|
|
25
|
-
print
|
26
|
+
print("#{runner.name}: ".ljust(label_width))
|
26
27
|
puts run(runner.new(RUNS))
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
31
|
def bmbm(runners)
|
31
|
-
label_width = runners.map{ |r| r.name.size }.max + 2
|
32
|
+
label_width = runners.map { |r| r.name.size }.max + 2
|
32
33
|
width = label_width + Benchmark::CAPTION.size
|
33
34
|
|
34
35
|
puts 'Rehearsal: '.ljust(width, '-')
|
data/performance/externals.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rubygems'
|
2
3
|
require 'benchmark'
|
3
4
|
require 'ruby-prof'
|
@@ -7,8 +8,8 @@ require_relative 'cache_runner'
|
|
7
8
|
RUNS = 1000
|
8
9
|
RubyProf.measure_mode = RubyProf::CPU_TIME
|
9
10
|
|
10
|
-
EXTERNALS = {"Memcache" => ["MemCache#set", "MemCache#get"],
|
11
|
-
|
11
|
+
EXTERNALS = { "Memcache" => ["MemCache#set", "MemCache#get"],
|
12
|
+
"Database" => ["Mysql2::Client#query"] }
|
12
13
|
|
13
14
|
def run(obj)
|
14
15
|
obj.prepare
|
@@ -26,7 +27,7 @@ def count_externals(results)
|
|
26
27
|
count = {}
|
27
28
|
results.split(/\n/).each do |line|
|
28
29
|
fields = line.split
|
29
|
-
if ext = EXTERNALS.detect { |e| e[1].any? { |method| method == fields[-1] } }
|
30
|
+
if (ext = EXTERNALS.detect { |e| e[1].any? { |method| method == fields[-1] } })
|
30
31
|
count[ext[0]] ||= 0
|
31
32
|
count[ext[0]] += fields[-2].to_i
|
32
33
|
end
|
data/performance/profile.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rubygems'
|
2
3
|
require 'benchmark'
|
3
4
|
require 'stackprof'
|
@@ -21,15 +22,15 @@ end
|
|
21
22
|
|
22
23
|
create_database(RUNS)
|
23
24
|
|
24
|
-
if runner_name = ENV['RUNNER']
|
25
|
-
if runner = CACHE_RUNNERS.find{ |r| r.name == runner_name }
|
25
|
+
if (runner_name = ENV['RUNNER'])
|
26
|
+
if (runner = CACHE_RUNNERS.find { |r| r.name == runner_name })
|
26
27
|
run(runner.new(RUNS), filename: ENV['FILENAME'])
|
27
28
|
else
|
28
29
|
puts "Couldn't find cache runner #{runner_name.inspect}"
|
29
|
-
exit
|
30
|
+
exit(1)
|
30
31
|
end
|
31
32
|
else
|
32
|
-
CACHE_RUNNERS.each do |
|
33
|
-
run(
|
33
|
+
CACHE_RUNNERS.each do |cache_runner|
|
34
|
+
run(cache_runner.new(RUNS))
|
34
35
|
end
|
35
36
|
end
|
data/railgun.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# https://dev-accel.shopify.io/dev/railgun/Railgun-Config
|
2
|
+
name: identity-cache
|
3
|
+
|
4
|
+
vm:
|
5
|
+
image: /opt/dev/misc/railgun-images/default
|
6
|
+
ip_address: 192.168.64.98
|
7
|
+
memory: 1G
|
8
|
+
cores: 2
|
9
|
+
|
10
|
+
volumes:
|
11
|
+
root: 1G
|
12
|
+
|
13
|
+
services:
|
14
|
+
- mysql
|
15
|
+
- postgresql
|
16
|
+
- memcached
|