methodmissing-scrooge 1.0.4 → 2.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.
- data/README.textile +139 -449
- data/Rakefile +20 -19
- data/VERSION.yml +2 -2
- data/lib/attributes_proxy.rb +121 -0
- data/lib/scrooge.rb +206 -47
- data/rails/init.rb +1 -10
- data/test/helper.rb +88 -0
- data/test/models/mysql_user.rb +4 -0
- data/test/scrooge_test.rb +75 -0
- data/test/setup.rb +3 -0
- metadata +11 -76
- data/assets/config/scrooge.yml.template +0 -27
- data/lib/scrooge/core/string.rb +0 -29
- data/lib/scrooge/core/symbol.rb +0 -21
- data/lib/scrooge/core/thread.rb +0 -26
- data/lib/scrooge/framework/base.rb +0 -315
- data/lib/scrooge/framework/rails.rb +0 -132
- data/lib/scrooge/middleware/tracker.rb +0 -46
- data/lib/scrooge/orm/active_record.rb +0 -159
- data/lib/scrooge/orm/base.rb +0 -102
- data/lib/scrooge/profile.rb +0 -223
- data/lib/scrooge/storage/base.rb +0 -46
- data/lib/scrooge/storage/memory.rb +0 -25
- data/lib/scrooge/strategy/base.rb +0 -74
- data/lib/scrooge/strategy/controller.rb +0 -31
- data/lib/scrooge/strategy/scope.rb +0 -15
- data/lib/scrooge/strategy/stage.rb +0 -77
- data/lib/scrooge/strategy/track.rb +0 -19
- data/lib/scrooge/strategy/track_then_scope.rb +0 -41
- data/lib/scrooge/tracker/app.rb +0 -161
- data/lib/scrooge/tracker/base.rb +0 -66
- data/lib/scrooge/tracker/model.rb +0 -150
- data/lib/scrooge/tracker/resource.rb +0 -181
- data/spec/fixtures/config/scrooge/scopes/1234567891/scope.yml +0 -2
- data/spec/fixtures/config/scrooge.yml +0 -20
- data/spec/helpers/framework/rails/cache.rb +0 -25
- data/spec/spec_helper.rb +0 -55
- data/spec/units/scrooge/core/string_spec.rb +0 -21
- data/spec/units/scrooge/core/symbol_spec.rb +0 -13
- data/spec/units/scrooge/core/thread_spec.rb +0 -15
- data/spec/units/scrooge/framework/base_spec.rb +0 -160
- data/spec/units/scrooge/framework/rails_spec.rb +0 -40
- data/spec/units/scrooge/orm/base_spec.rb +0 -61
- data/spec/units/scrooge/profile_spec.rb +0 -79
- data/spec/units/scrooge/storage/base_spec.rb +0 -35
- data/spec/units/scrooge/storage/memory_spec.rb +0 -20
- data/spec/units/scrooge/strategy/base_spec.rb +0 -62
- data/spec/units/scrooge/strategy/controller_spec.rb +0 -26
- data/spec/units/scrooge/strategy/scope_spec.rb +0 -18
- data/spec/units/scrooge/strategy/stage_spec.rb +0 -35
- data/spec/units/scrooge/strategy/track_spec.rb +0 -19
- data/spec/units/scrooge/strategy/track_then_scope_spec.rb +0 -22
- data/spec/units/scrooge/tracker/app_spec.rb +0 -68
- data/spec/units/scrooge/tracker/base_spec.rb +0 -29
- data/spec/units/scrooge/tracker/model_spec.rb +0 -79
- data/spec/units/scrooge/tracker/resource_spec.rb +0 -115
- data/spec/units/scrooge_spec.rb +0 -13
- data/tasks/scrooge.rake +0 -43
@@ -1,159 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Orm
|
3
|
-
class ActiveRecord < Base
|
4
|
-
module ScroogeAttributes
|
5
|
-
|
6
|
-
module SingletonMethods
|
7
|
-
|
8
|
-
private
|
9
|
-
|
10
|
-
# Define an attribute reader method. Cope with nil column.
|
11
|
-
def define_read_method(symbol, attr_name, column)
|
12
|
-
cast_code = column.type_cast_code('v') if column
|
13
|
-
access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
|
14
|
-
|
15
|
-
unless attr_name.to_s == self.primary_key.to_s
|
16
|
-
access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
|
17
|
-
end
|
18
|
-
|
19
|
-
if cache_attribute?(attr_name)
|
20
|
-
access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})"
|
21
|
-
end
|
22
|
-
evaluate_attribute_method attr_name, "def #{symbol}; register_with_scrooge!(:#{attr_name}, 'define read method' ); #{access_code}; end"
|
23
|
-
end
|
24
|
-
|
25
|
-
# Define read method for serialized attribute.
|
26
|
-
def define_read_method_for_serialized_attribute(attr_name)
|
27
|
-
evaluate_attribute_method attr_name, "def #{attr_name}; register_with_scrooge!(:#{attr_name}, 'define read method for serialized attribute' ); unserialize_attribute('#{attr_name}'); end"
|
28
|
-
end
|
29
|
-
|
30
|
-
# Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
|
31
|
-
# This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone.
|
32
|
-
def define_read_method_for_time_zone_conversion(attr_name)
|
33
|
-
method_body = <<-EOV
|
34
|
-
def #{attr_name}(reload = false)
|
35
|
-
register_with_scrooge!(:#{attr_name}, 'define read method for time zone conversion' )
|
36
|
-
cached = @attributes_cache['#{attr_name}']
|
37
|
-
return cached if cached && !reload
|
38
|
-
time = read_attribute('#{attr_name}')
|
39
|
-
@attributes_cache['#{attr_name}'] = time.acts_like?(:time) ? time.in_time_zone : time
|
40
|
-
end
|
41
|
-
EOV
|
42
|
-
evaluate_attribute_method attr_name, method_body
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
module InstanceMethods
|
48
|
-
|
49
|
-
# Attach to AR::Base#read_attribute.
|
50
|
-
#
|
51
|
-
def read_attribute(attr_name)
|
52
|
-
register_with_scrooge!( attr_name, 'read attribute' )
|
53
|
-
super( attr_name )
|
54
|
-
end
|
55
|
-
|
56
|
-
# Attach to AR::Base#read_attribute_before_typecast.
|
57
|
-
#
|
58
|
-
def read_attribute_before_type_cast(attr_name)
|
59
|
-
register_with_scrooge!( attr_name, 'read attribute before type cast' )
|
60
|
-
super(attr_name)
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def register_with_scrooge!( attr_name, caller ) #:nodoc:
|
66
|
-
if ::Scrooge::Base.profile.orm.track?
|
67
|
-
# Avoid string interpolation if not required
|
68
|
-
::Scrooge::Base.profile.log( "Register attribute #{attr_name.inspect} from #{caller}" ) if ::Scrooge::Base.profile.verbose?
|
69
|
-
Thread.scrooge_resource << [self.class.base_class, attr_name]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def missing_attribute(attr_name, stack) #:nodoc:
|
74
|
-
if Scrooge::Base.profile.raise_on_missing_attribute?
|
75
|
-
super(attr_name, stack)
|
76
|
-
else
|
77
|
-
logger.info "[Scrooge] missing attribute #{attr_name.to_s}"
|
78
|
-
reload( :select => '*' )
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
class << self
|
87
|
-
|
88
|
-
# Inject Scrooge ActiveRecord attribute tracking.
|
89
|
-
#
|
90
|
-
def install!
|
91
|
-
::ActiveRecord::Base.send( :extend, Scrooge::Orm::ActiveRecord::ScroogeAttributes::SingletonMethods )
|
92
|
-
::ActiveRecord::Base.send( :include, Scrooge::Orm::ActiveRecord::ScroogeAttributes::InstanceMethods )
|
93
|
-
end
|
94
|
-
|
95
|
-
# Determine if the ActiveRecord attribute tracker has already been installed.
|
96
|
-
#
|
97
|
-
def installed?
|
98
|
-
begin
|
99
|
-
::ActiveRecord::Base.included_modules.include?( Scrooge::Orm::ActiveRecord::ScroogeAttributes )
|
100
|
-
rescue => exception
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
# Generate scope helpers for a given resource.
|
107
|
-
#
|
108
|
-
def scope_to( resource )
|
109
|
-
resource.models.each do |model|
|
110
|
-
scope_resource_to_model( resource, model )
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Generate scope helpers for a given model and resource.
|
115
|
-
#
|
116
|
-
def scope_resource_to_model( resource, model )
|
117
|
-
method_name = resource_scope_method( resource )
|
118
|
-
klass = klass_for_model( model )
|
119
|
-
unless resource_scope_method?( resource, klass )
|
120
|
-
klass.instance_eval(<<-EOS, __FILE__, __LINE__)
|
121
|
-
def #{method_name}
|
122
|
-
with_scope( { :find => { :select => '#{model.to_sql}' } }) do
|
123
|
-
yield
|
124
|
-
end
|
125
|
-
end
|
126
|
-
EOS
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# Returns a lookup key from a given String or AR klass
|
131
|
-
#
|
132
|
-
def name( model )
|
133
|
-
model = model.to_const!(false) if model.is_a?(String)
|
134
|
-
model.respond_to?(:base_class) ? model.base_class.to_s : model.to_s
|
135
|
-
end
|
136
|
-
|
137
|
-
# Returns a table name from a given String or AR klass
|
138
|
-
#
|
139
|
-
def table_name( model )
|
140
|
-
model = model.to_const!(false) if model.is_a?(String)
|
141
|
-
model.table_name
|
142
|
-
end
|
143
|
-
|
144
|
-
# Returns a primary key from a given String or AR klass
|
145
|
-
#
|
146
|
-
def primary_key( model )
|
147
|
-
model = model.to_const!(false) if model.is_a?(String)
|
148
|
-
model.primary_key
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
|
-
|
153
|
-
def klass_for_model( model ) #:nodoc:
|
154
|
-
model.model.is_a?(String) ? model.model.to_const!(false) : model.model
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
data/lib/scrooge/orm/base.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Orm
|
3
|
-
|
4
|
-
autoload :ActiveRecord, 'scrooge/orm/active_record'
|
5
|
-
|
6
|
-
class Base < Scrooge::Base
|
7
|
-
|
8
|
-
# ORM agnostic base class.
|
9
|
-
|
10
|
-
class NotImplemented < StandardError
|
11
|
-
end
|
12
|
-
|
13
|
-
class << self
|
14
|
-
|
15
|
-
# Instantiate and optionally install from a given ORM signature.
|
16
|
-
#
|
17
|
-
def instantiate( orm_signature )
|
18
|
-
orm_instance = "scrooge/orm/#{orm_signature.to_s}".to_const!
|
19
|
-
orm_instance.class.install! unless orm_instance.class.installed?
|
20
|
-
orm_instance
|
21
|
-
end
|
22
|
-
|
23
|
-
# Subclasses is required to implemented an installation hook.
|
24
|
-
#
|
25
|
-
def install!
|
26
|
-
raise NotImplemented
|
27
|
-
end
|
28
|
-
|
29
|
-
# Subclasses should be able to determine if it's already been injected into
|
30
|
-
# the underlying ORM package.
|
31
|
-
#
|
32
|
-
def installed?
|
33
|
-
raise NotImplemented
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
# Generate scope helpers for a Resource and it's related Model trackers.
|
39
|
-
#
|
40
|
-
def scope_to( resource )
|
41
|
-
raise NotImplemented
|
42
|
-
end
|
43
|
-
|
44
|
-
# Generate scope helpers for a given Resource and Model tracker.
|
45
|
-
#
|
46
|
-
def scope_resource_to_model( resource, model )
|
47
|
-
raise NotImplemented
|
48
|
-
end
|
49
|
-
|
50
|
-
# Returns a lookup key from a given String or class
|
51
|
-
#
|
52
|
-
def name( model )
|
53
|
-
raise NotImplemented
|
54
|
-
end
|
55
|
-
|
56
|
-
# Returns a table name from a given String or class
|
57
|
-
#
|
58
|
-
def table_name( model )
|
59
|
-
raise NotImplemented
|
60
|
-
end
|
61
|
-
|
62
|
-
# Returns a primary key from a given String or class
|
63
|
-
#
|
64
|
-
def primary_key( model )
|
65
|
-
raise NotImplemented
|
66
|
-
end
|
67
|
-
|
68
|
-
# Generates a sanitized method name for a given resource.
|
69
|
-
#
|
70
|
-
def resource_scope_method( resource )
|
71
|
-
"scope_to_#{resource.signature}".to_sym
|
72
|
-
end
|
73
|
-
|
74
|
-
# Determine if a scope method has already been generated for a given
|
75
|
-
# Resource and klass.
|
76
|
-
#
|
77
|
-
def resource_scope_method?( resource, klass )
|
78
|
-
klass.respond_to?( resource_scope_method( resource ) )
|
79
|
-
end
|
80
|
-
|
81
|
-
# Only track if the current profile is configured for tracking and a tracker
|
82
|
-
# resource is active, iow. we're in the scope of a request.
|
83
|
-
#
|
84
|
-
def track?
|
85
|
-
profile.track? && resource?
|
86
|
-
end
|
87
|
-
|
88
|
-
# Do we have access to Resource Tracker instance ?
|
89
|
-
#
|
90
|
-
def resource?
|
91
|
-
!resource().nil?
|
92
|
-
end
|
93
|
-
|
94
|
-
# Delegate to Thread.current
|
95
|
-
#
|
96
|
-
def resource
|
97
|
-
Thread.current[:scrooge_resource]
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
data/lib/scrooge/profile.rb
DELETED
@@ -1,223 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module Scrooge
|
4
|
-
class Profile
|
5
|
-
|
6
|
-
# A Profile for Scrooge that holds configuration, determines if we're tracking or
|
7
|
-
# scoping and provides access to a Tracker, ORM, Storage and Framework instance.
|
8
|
-
|
9
|
-
GUARD = Mutex.new
|
10
|
-
|
11
|
-
class << self
|
12
|
-
|
13
|
-
# Setup a new instance from the path to a YAML configuration file and a
|
14
|
-
# given environment.
|
15
|
-
#
|
16
|
-
def setup( path, environment )
|
17
|
-
begin
|
18
|
-
new( read_config( path, environment ) )
|
19
|
-
rescue ::Errno::ENOENT
|
20
|
-
puts "Scrooge Configuration file not available."
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Pairs profile setup with the host framework.
|
25
|
-
#
|
26
|
-
def setup!
|
27
|
-
setup( framework.configuration_file, framework.environment )
|
28
|
-
end
|
29
|
-
|
30
|
-
# Yields an instance to a wrapper of the host framework.
|
31
|
-
#
|
32
|
-
def framework
|
33
|
-
@@framework ||= Scrooge::Framework::Base.instantiate
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def read_config( path, environment ) #:nodoc:
|
39
|
-
YAML.load( IO.read( path ) )[environment.to_s]
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
attr_reader :options
|
45
|
-
|
46
|
-
def initialize( options = {} )
|
47
|
-
self.options = options
|
48
|
-
end
|
49
|
-
|
50
|
-
# options writer that attempts to reconfigure for any configuration changes.
|
51
|
-
#
|
52
|
-
def options=( options )
|
53
|
-
@options = options
|
54
|
-
configure!
|
55
|
-
end
|
56
|
-
|
57
|
-
# Delegates to the underlying ORM framework.
|
58
|
-
#
|
59
|
-
def orm
|
60
|
-
@orm_instance ||= Scrooge::Orm::Base.instantiate( @orm )
|
61
|
-
end
|
62
|
-
|
63
|
-
# Delegates to the current storage backend.
|
64
|
-
#
|
65
|
-
def storage
|
66
|
-
@storage_instance ||= Scrooge::Storage::Base.instantiate( @storage )
|
67
|
-
end
|
68
|
-
|
69
|
-
# Delegates to the Application Tracker.
|
70
|
-
#
|
71
|
-
def tracker
|
72
|
-
@tracker_instance ||= Scrooge::Tracker::App.new
|
73
|
-
end
|
74
|
-
|
75
|
-
# Yields a strategt instance.
|
76
|
-
#
|
77
|
-
def strategy
|
78
|
-
@strategy_instance ||= "scrooge/strategy/#{@strategy.to_s}".to_const!
|
79
|
-
end
|
80
|
-
|
81
|
-
# Delegates to the current framework.
|
82
|
-
#
|
83
|
-
def framework
|
84
|
-
self.class.framework
|
85
|
-
end
|
86
|
-
|
87
|
-
# Log a message to the framework's logger.
|
88
|
-
#
|
89
|
-
def log( message, flush = false )
|
90
|
-
framework.log( message, flush ) rescue ''
|
91
|
-
end
|
92
|
-
|
93
|
-
# Log a message to the framework's logger.
|
94
|
-
#
|
95
|
-
def verbose_log( message, flush = false )
|
96
|
-
log( message, flush ) if verbose?
|
97
|
-
end
|
98
|
-
|
99
|
-
# Are we tracking ?
|
100
|
-
#
|
101
|
-
def track?
|
102
|
-
GUARD.synchronize do
|
103
|
-
@track == true
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Enable the tracking phase
|
108
|
-
#
|
109
|
-
def start_tracking!
|
110
|
-
GUARD.synchronize do
|
111
|
-
@track = true
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Disable the tracking phase
|
116
|
-
#
|
117
|
-
def stop_tracking!
|
118
|
-
GUARD.synchronize do
|
119
|
-
@track = false
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# The active scope signature
|
124
|
-
#
|
125
|
-
def scope
|
126
|
-
@scope
|
127
|
-
end
|
128
|
-
|
129
|
-
# Assign the current scope from a given signature or tracker
|
130
|
-
#
|
131
|
-
def scope=( signature_or_tracker )
|
132
|
-
if signature_or_tracker.kind_of?( Scrooge::Tracker::Base )
|
133
|
-
scope_to_tracker!( signature_or_tracker )
|
134
|
-
else
|
135
|
-
scope_to_signature!( signature_or_tracker )
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# Should Scrooge inject itself ?
|
140
|
-
#
|
141
|
-
def enabled?
|
142
|
-
@enabled
|
143
|
-
end
|
144
|
-
|
145
|
-
# Should Scrooge be chatty ?
|
146
|
-
#
|
147
|
-
def verbose?
|
148
|
-
@verbose
|
149
|
-
end
|
150
|
-
|
151
|
-
# Should we raise on missing attributes ?
|
152
|
-
#
|
153
|
-
def raise_on_missing_attribute?
|
154
|
-
@on_missing_attribute == :raise
|
155
|
-
end
|
156
|
-
|
157
|
-
# Expose the warmup phase during which tracking occur.
|
158
|
-
#
|
159
|
-
def warmup
|
160
|
-
@warmup
|
161
|
-
end
|
162
|
-
|
163
|
-
# A session key that indicates a logged in / private session.
|
164
|
-
#
|
165
|
-
def logged_in_session
|
166
|
-
@logged_in_session
|
167
|
-
end
|
168
|
-
|
169
|
-
private
|
170
|
-
|
171
|
-
def configure! #:nodoc:
|
172
|
-
@orm = configure_with( @options['orm'], [:active_record], :active_record )
|
173
|
-
@storage = configure_with( @options['storage'], [:memory], :memory )
|
174
|
-
@strategy = configure_with( @options['strategy'], [:track, :scope, :track_then_scope], :track )
|
175
|
-
@scope = configure_with( @options['scope'].to_s, framework_scopes, ENV['scope'] )
|
176
|
-
@warmup = configure_with( @options['warmup'], 0..14400, 0 )
|
177
|
-
@enabled = configure_with( @options['enabled'], [true, false], false )
|
178
|
-
@on_missing_attribute = configure_with( @options['on_missing_attribute'], [:reload, :raise], :reload )
|
179
|
-
@verbose = configure_with( @options['verbose'], [true, false], false )
|
180
|
-
@logged_in_session = configure_with( @options['logged_in_session'], nil, :user_id )
|
181
|
-
reset_backends!
|
182
|
-
memoize_backends!
|
183
|
-
end
|
184
|
-
|
185
|
-
def configure_with( given, valid, default ) #:nodoc:
|
186
|
-
if given
|
187
|
-
valid && valid.include?( given ) ? given : default
|
188
|
-
else
|
189
|
-
default
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def framework_scopes #:nodoc:
|
194
|
-
framework.scopes rescue []
|
195
|
-
end
|
196
|
-
|
197
|
-
def reset_backends! #:nodoc:
|
198
|
-
@orm_instance = nil
|
199
|
-
@tracker_instance = nil
|
200
|
-
@storage_instance = nil
|
201
|
-
end
|
202
|
-
|
203
|
-
# Force constant lookups as autoload is not threadsafe.
|
204
|
-
#
|
205
|
-
def memoize_backends! #:nodoc:
|
206
|
-
framework() rescue nil
|
207
|
-
orm()
|
208
|
-
storage()
|
209
|
-
tracker()
|
210
|
-
end
|
211
|
-
|
212
|
-
def scope_to_signature!( scope_signature ) #:nodoc:
|
213
|
-
log "Scope to signature #{scope_signature} ..."
|
214
|
-
@tracker_instance = framework.from_scope!( scope_signature )
|
215
|
-
end
|
216
|
-
|
217
|
-
def scope_to_tracker!( tracker ) #:nodoc:
|
218
|
-
log "Scope to tracker #{tracker.inspect} ..."
|
219
|
-
@tracker_instance = tracker
|
220
|
-
end
|
221
|
-
|
222
|
-
end
|
223
|
-
end
|
data/lib/scrooge/storage/base.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Storage
|
3
|
-
|
4
|
-
autoload :Memory, 'scrooge/storage/memory'
|
5
|
-
|
6
|
-
class Base < Scrooge::Base
|
7
|
-
class NotImplemented < StandardError
|
8
|
-
end
|
9
|
-
|
10
|
-
# A Single Mutex for all Storage subclasses as their's only one storage instance.
|
11
|
-
#
|
12
|
-
GUARD = Mutex.new
|
13
|
-
|
14
|
-
NAMESPACE = 'scrooge_storage'.freeze
|
15
|
-
|
16
|
-
class << self
|
17
|
-
|
18
|
-
# Yields a storage instance from a given signature.
|
19
|
-
#
|
20
|
-
def instantiate( storage_signature )
|
21
|
-
"scrooge/storage/#{storage_signature.to_s}".to_const!
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
# Retrieve a given tracker from storage.
|
27
|
-
#
|
28
|
-
def read( tracker )
|
29
|
-
raise NotImplemented
|
30
|
-
end
|
31
|
-
|
32
|
-
# Persist a given tracker to storage.
|
33
|
-
#
|
34
|
-
def write( tracker, buffered = true )
|
35
|
-
raise NotImplemented
|
36
|
-
end
|
37
|
-
|
38
|
-
# Namespace lookup keys.
|
39
|
-
#
|
40
|
-
def expand_key( key )
|
41
|
-
"#{NAMESPACE}/#{key}"
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Storage
|
3
|
-
class Memory < Base
|
4
|
-
|
5
|
-
attr_reader :storage
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@storage = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
def read( tracker )
|
12
|
-
GUARD.synchronize do
|
13
|
-
@storage[tracker.signature]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def write( tracker, buffered = true )
|
18
|
-
GUARD.synchronize do
|
19
|
-
@storage[tracker.signature] = tracker
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Strategy
|
3
|
-
|
4
|
-
autoload :Controller, 'scrooge/strategy/controller'
|
5
|
-
autoload :Stage, 'scrooge/strategy/stage'
|
6
|
-
autoload :Scope, 'scrooge/strategy/scope'
|
7
|
-
autoload :Track, 'scrooge/strategy/track'
|
8
|
-
autoload :TrackThenScope, 'scrooge/strategy/track_then_scope'
|
9
|
-
|
10
|
-
class Base
|
11
|
-
|
12
|
-
class NoStages < StandardError
|
13
|
-
end
|
14
|
-
|
15
|
-
@@stages = Hash.new( [] )
|
16
|
-
@@stages[self.name] = []
|
17
|
-
|
18
|
-
attr_reader :thread
|
19
|
-
|
20
|
-
class << self
|
21
|
-
|
22
|
-
# Stage definition macro.
|
23
|
-
#
|
24
|
-
# stage :track, :for => 10.minutes do
|
25
|
-
# ....
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
def stage( signature, options = {}, &block )
|
29
|
-
@@stages[self.name] << Scrooge::Strategy::Stage.new( signature, options, &block )
|
30
|
-
end
|
31
|
-
|
32
|
-
# List all defined stages for this klass.
|
33
|
-
#
|
34
|
-
def stages
|
35
|
-
@@stages[self.name]
|
36
|
-
end
|
37
|
-
|
38
|
-
# Are there any stages defined ?
|
39
|
-
#
|
40
|
-
def stages?
|
41
|
-
!stages.empty?
|
42
|
-
end
|
43
|
-
|
44
|
-
# Test teardown helper.
|
45
|
-
#
|
46
|
-
def flush!
|
47
|
-
@@stages[self.name] = []
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
# Requires at least one stage definition.
|
53
|
-
#
|
54
|
-
def initialize
|
55
|
-
raise NoStages unless self.class.stages?
|
56
|
-
end
|
57
|
-
|
58
|
-
# Piggy back on stages defined for this klass.
|
59
|
-
#
|
60
|
-
def stages
|
61
|
-
self.class.stages
|
62
|
-
end
|
63
|
-
|
64
|
-
# Enforce this strategy
|
65
|
-
#
|
66
|
-
def execute!
|
67
|
-
if Scrooge::Base.profile.enabled?
|
68
|
-
@thread = Scrooge::Strategy::Controller.new( self ).run!
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Scrooge
|
2
|
-
module Strategy
|
3
|
-
class Controller
|
4
|
-
|
5
|
-
attr_accessor :strategy
|
6
|
-
attr_reader :thread
|
7
|
-
|
8
|
-
def initialize( strategy )
|
9
|
-
@strategy = strategy
|
10
|
-
end
|
11
|
-
|
12
|
-
# Execute a given strategy
|
13
|
-
#
|
14
|
-
def run!
|
15
|
-
@thread = Thread.new do
|
16
|
-
Thread.current.abort_on_exception = true
|
17
|
-
stages.map do |stage|
|
18
|
-
stage.execute!
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def stages #:nodoc:
|
26
|
-
@strategy.stages
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|