Class: Vanity::Playground
Overview
Playground catalogs all your experiments, holds the Vanity configuration.
Constant Summary collapse
- DEFAULTS =
{ :collecting => true, :load_path=>"experiments" }
Instance Attribute Summary collapse
-
#db ⇒ Object
Deprecated.
-
#host ⇒ Object
Deprecated.
-
#load_path ⇒ Object
Path to load experiment files from.
-
#logger ⇒ Object
Logger.
-
#namespace ⇒ Object
Deprecated.
-
#password ⇒ Object
Deprecated.
-
#port ⇒ Object
Deprecated.
Instance Method Summary collapse
-
#collecting=(enabled) ⇒ Object
Turns data collection on and off.
-
#collecting? ⇒ Boolean
True if collection data (metrics and experiments).
-
#connected? ⇒ Boolean
Returns true if connection is open.
-
#connection ⇒ Object
Returns the current connection.
-
#define(name, type, options = {}, &block) ⇒ Object
Defines a new experiment.
-
#disconnect! ⇒ Object
Closes the current connection.
-
#establish_connection(spec = nil) ⇒ Object
This is the preferred way to programmatically create a new connection (or switch to a new connection).
-
#experiment(name) ⇒ Object
Returns the experiment.
-
#experiments ⇒ Object
Returns hash of experiments (key is experiment id).
-
#initialize(*args) ⇒ Playground
constructor
Created new Playground.
-
#load! ⇒ Object
Loads all metrics and experiments.
-
#metric(id) ⇒ Object
Returns a metric (raises NameError if no metric with that identifier).
-
#metrics ⇒ Object
Returns hash of metrics (key is metric id).
-
#reconnect! ⇒ Object
Closes the current connection and establishes a new one.
- #redis ⇒ Object
-
#redis=(spec_or_connection) ⇒ Object
Deprecated.
-
#reload! ⇒ Object
Reloads all metrics and experiments.
-
#test! ⇒ Object
Deprecated.
-
#track!(id, count = 1) ⇒ Object
Tracks an action associated with a metric.
Constructor Details
#initialize(*args) ⇒ Playground
Created new Playground. Unless you need to, use the global Vanity.playground.
First argument is connection specification (see #redis=), last argument is a set of options, both are optional. Supported options are:
-
connection – Connection specification
-
namespace – Namespace to use
-
load_path – Path to load experiments/metrics from
-
logger – Logger to use
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/vanity/playground.rb', line 23 def initialize(*args) = args.pop if Hash === args.last @options = DEFAULTS.merge( || {}) if @options.values_at(:host, :port, :db).any? warn "Deprecated: please specify Redis connection as URL (\"redis://host:port/db\")" establish_connection :adapter=>"redis", :host=>[:host], :port=>[:port], :database=>[:db] elsif @options[:redis] @adapter = RedisAdapter.new(:redis=>@options[:redis]) else connection_spec = args.shift || @options[:connection] establish_connection "redis://" + connection_spec if connection_spec end warn "Deprecated: namespace option no longer supported directly" if @options[:namespace] @load_path = @options[:load_path] || DEFAULTS[:load_path] unless @logger = @options[:logger] @logger = Logger.new(STDOUT) @logger.level = Logger::ERROR end @loading = [] @collecting = @options[:collecting] end |
Instance Attribute Details
#db ⇒ Object
Deprecated. Use redis.server instead.
47 48 49 |
# File 'lib/vanity/playground.rb', line 47 def db @db end |
#host ⇒ Object
Deprecated. Use redis.server instead.
47 48 49 |
# File 'lib/vanity/playground.rb', line 47 def host @host end |
#load_path ⇒ Object
Path to load experiment files from.
50 51 52 |
# File 'lib/vanity/playground.rb', line 50 def load_path @load_path end |
#namespace ⇒ Object
Deprecated. Use redis.server instead.
47 48 49 |
# File 'lib/vanity/playground.rb', line 47 def namespace @namespace end |
#password ⇒ Object
Deprecated. Use redis.server instead.
47 48 49 |
# File 'lib/vanity/playground.rb', line 47 def password @password end |
#port ⇒ Object
Deprecated. Use redis.server instead.
47 48 49 |
# File 'lib/vanity/playground.rb', line 47 def port @port end |
Instance Method Details
#collecting=(enabled) ⇒ Object
Turns data collection on and off.
129 130 131 |
# File 'lib/vanity/playground.rb', line 129 def collecting=(enabled) @collecting = !!enabled end |
#collecting? ⇒ Boolean
True if collection data (metrics and experiments). You only want to collect data in production environment, everywhere else run with collection off.
122 123 124 |
# File 'lib/vanity/playground.rb', line 122 def collecting? @collecting end |
#connected? ⇒ Boolean
Returns true if connection is open.
238 239 240 |
# File 'lib/vanity/playground.rb', line 238 def connected? @adapter && @adapter.active? end |
#connection ⇒ Object
Returns the current connection. Establishes new connection is necessary.
231 232 233 |
# File 'lib/vanity/playground.rb', line 231 def connection @adapter || establish_connection end |
#define(name, type, options = {}, &block) ⇒ Object
Defines a new experiment. Generally, do not call this directly, use one of the definition methods (ab_test, measure, etc).
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/vanity/playground.rb', line 59 def define(name, type, = {}, &block) warn "Deprecated: if you need this functionality let's make a better API" id = name.to_s.downcase.gsub(/\W/, "_").to_sym raise "Experiment #{id} already defined once" if experiments[id] klass = Experiment.const_get(type.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }) experiment = klass.new(self, id, name, ) experiment.instance_eval &block experiment.save experiments[id] = experiment end |
#disconnect! ⇒ Object
Closes the current connection.
245 246 247 |
# File 'lib/vanity/playground.rb', line 245 def disconnect! @adapter.disconnect! if @adapter end |
#establish_connection(spec = nil) ⇒ Object
This is the preferred way to programmatically create a new connection (or switch to a new connection). If no connection was established, the playground will create a new one by calling this method with no arguments.
With no argument, uses the connection specified in config/vanity.yml file for the current environment (RACK_ENV, RAILS_ENV or development). If there is no config/vanity.yml file, picks the configuration from config/redis.yml, or defaults to Redis on localhost, port 6379.
If the argument is a symbol, uses the connection specified in config/vanity.yml for that environment. For example:
Vanity.playground.establish_connection :production
If the argument is a string, it is processed as a URL. For example:
Vanity.playground.establish_connection "redis://redis.local/5"
Otherwise, the argument is a hash and specifies the adapter name and any additional options understood by that adapter (as with config/vanity.yml). For example:
Vanity.playground.establish_connection :adapter=>:redis,
:host=>"redis.local"
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/vanity/playground.rb', line 192 def establish_connection(spec = nil) disconnect! if @adapter case spec when nil if File.exists?("config/vanity.yml") env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development" spec = YAML.load(ERB.new(File.read("config/vanity.yml")).result)[env] fail "No configuration for #{env}" unless spec establish_connection spec elsif File.exists?("config/redis.yml") env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development" redis = YAML.load(ERB.new(File.read("config/redis.yml")).result)[env] fail "No configuration for #{env}" unless redis establish_connection "redis://" + redis else establish_connection :adapter=>"redis" end when Symbol spec = YAML.load(ERB.new(File.read("config/vanity.yml")).result)[spec.to_s] establish_connection spec when String uri = URI.parse(spec) params = CGI.parse(uri.query) if uri.query establish_connection :adapter=>uri.scheme, :username=>uri.user, :password=>uri.password, :host=>uri.host, :port=>uri.port, :path=>uri.path, :params=>params else spec = spec.inject({}) { |hash,(k,v)| hash[k.to_sym] = v ; hash } begin require "vanity/adapters/#{spec[:adapter]}_adapter" rescue LoadError raise "Could not find #{spec[:adapter]} in your load path" end @adapter = Adapters.establish_connection(spec) end end |
#experiment(name) ⇒ Object
Returns the experiment. You may not have guessed, but this method raises an exception if it cannot load the experiment’s definition.
74 75 76 77 78 |
# File 'lib/vanity/playground.rb', line 74 def experiment(name) id = name.to_s.downcase.gsub(/\W/, "_").to_sym warn "Deprecated: pleae call experiment method with experiment identifier (a Ruby symbol)" unless id == name experiments[id.to_sym] or raise NameError, "No experiment #{id}" end |
#experiments ⇒ Object
Returns hash of experiments (key is experiment id).
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/vanity/playground.rb', line 83 def experiments unless @experiments @experiments = {} @logger.info "Vanity: loading experiments from #{load_path}" Dir[File.join(load_path, "*.rb")].each do |file| Experiment::Base.load self, @loading, file end end @experiments end |
#load! ⇒ Object
Loads all metrics and experiments. Rails calls this during initialization.
104 105 106 107 |
# File 'lib/vanity/playground.rb', line 104 def load! experiments metrics end |
#metric(id) ⇒ Object
Returns a metric (raises NameError if no metric with that identifier).
113 114 115 |
# File 'lib/vanity/playground.rb', line 113 def metric(id) metrics[id.to_sym] or raise NameError, "No metric #{id}" end |
#metrics ⇒ Object
Returns hash of metrics (key is metric id).
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/vanity/playground.rb', line 137 def metrics unless @metrics @metrics = {} @logger.info "Vanity: loading metrics from #{load_path}/metrics" Dir[File.join(load_path, "metrics/*.rb")].each do |file| Metric.load self, @loading, file end if File.exist?("config/vanity.yml") && remote = YAML.load(ERB.new(File.read("config/vanity.yml")).result)["metrics"] remote.each do |id, url| fail "Metric #{id} already defined in playground" if metrics[id.to_sym] metric = Metric.new(self, id) metric.remote url metrics[id.to_sym] = metric end end end @metrics end |
#reconnect! ⇒ Object
Closes the current connection and establishes a new one.
252 253 254 |
# File 'lib/vanity/playground.rb', line 252 def reconnect! establish_connection end |
#redis ⇒ Object
279 280 281 282 |
# File 'lib/vanity/playground.rb', line 279 def redis warn "Deprecated: use connection method instead" connection end |
#redis=(spec_or_connection) ⇒ Object
Deprecated. Use establish_connection or configuration file instead.
265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/vanity/playground.rb', line 265 def redis=(spec_or_connection) warn "Deprecated: use establish_connection method instead" case spec_or_connection when String establish_connection "redis://" + spec_or_connection when ::Redis @connection = Adapters::RedisAdapter.new(spec_or_connection) when :mock establish_connection :adapter=>:mock else raise "I don't know what to do with #{spec_or_connection.inspect}" end end |
#reload! ⇒ Object
Reloads all metrics and experiments. Rails calls this for each request in development mode.
96 97 98 99 100 |
# File 'lib/vanity/playground.rb', line 96 def reload! @experiments = nil @metrics = nil load! end |
#test! ⇒ Object
Deprecated. Use Vanity.playground.collecting = true/false instead. Under Rails, collecting is true in production environment, false in all other environments, which is exactly what you want.
259 260 261 262 |
# File 'lib/vanity/playground.rb', line 259 def test! warn "Deprecated: use collecting = false instead" self.collecting = false end |
#track!(id, count = 1) ⇒ Object
Tracks an action associated with a metric.
162 163 164 |
# File 'lib/vanity/playground.rb', line 162 def track!(id, count = 1) metric(id).track! count end |