mikeg-vanity 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +153 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +83 -0
- data/bin/vanity +53 -0
- data/lib/vanity.rb +38 -0
- data/lib/vanity/backport.rb +43 -0
- data/lib/vanity/commands.rb +2 -0
- data/lib/vanity/commands/list.rb +21 -0
- data/lib/vanity/commands/report.rb +60 -0
- data/lib/vanity/experiment/ab_test.rb +477 -0
- data/lib/vanity/experiment/base.rb +212 -0
- data/lib/vanity/helpers.rb +59 -0
- data/lib/vanity/metric/active_record.rb +77 -0
- data/lib/vanity/metric/base.rb +221 -0
- data/lib/vanity/metric/google_analytics.rb +70 -0
- data/lib/vanity/mock_redis.rb +76 -0
- data/lib/vanity/playground.rb +197 -0
- data/lib/vanity/rails.rb +22 -0
- data/lib/vanity/rails/dashboard.rb +24 -0
- data/lib/vanity/rails/helpers.rb +158 -0
- data/lib/vanity/rails/testing.rb +11 -0
- data/lib/vanity/templates/_ab_test.erb +26 -0
- data/lib/vanity/templates/_experiment.erb +5 -0
- data/lib/vanity/templates/_experiments.erb +7 -0
- data/lib/vanity/templates/_metric.erb +14 -0
- data/lib/vanity/templates/_metrics.erb +13 -0
- data/lib/vanity/templates/_report.erb +27 -0
- data/lib/vanity/templates/flot.min.js +1 -0
- data/lib/vanity/templates/jquery.min.js +19 -0
- data/lib/vanity/templates/vanity.css +26 -0
- data/lib/vanity/templates/vanity.js +82 -0
- data/test/ab_test_test.rb +656 -0
- data/test/experiment_test.rb +136 -0
- data/test/experiments/age_and_zipcode.rb +19 -0
- data/test/experiments/metrics/cheers.rb +3 -0
- data/test/experiments/metrics/signups.rb +2 -0
- data/test/experiments/metrics/yawns.rb +3 -0
- data/test/experiments/null_abc.rb +5 -0
- data/test/metric_test.rb +518 -0
- data/test/playground_test.rb +10 -0
- data/test/rails_test.rb +104 -0
- data/test/test_helper.rb +135 -0
- data/vanity.gemspec +18 -0
- data/vendor/redis-rb/LICENSE +20 -0
- data/vendor/redis-rb/README.markdown +36 -0
- data/vendor/redis-rb/Rakefile +62 -0
- data/vendor/redis-rb/bench.rb +44 -0
- data/vendor/redis-rb/benchmarking/suite.rb +24 -0
- data/vendor/redis-rb/benchmarking/worker.rb +71 -0
- data/vendor/redis-rb/bin/distredis +33 -0
- data/vendor/redis-rb/examples/basic.rb +16 -0
- data/vendor/redis-rb/examples/incr-decr.rb +18 -0
- data/vendor/redis-rb/examples/list.rb +26 -0
- data/vendor/redis-rb/examples/sets.rb +36 -0
- data/vendor/redis-rb/lib/dist_redis.rb +124 -0
- data/vendor/redis-rb/lib/hash_ring.rb +128 -0
- data/vendor/redis-rb/lib/pipeline.rb +21 -0
- data/vendor/redis-rb/lib/redis.rb +370 -0
- data/vendor/redis-rb/lib/redis/raketasks.rb +1 -0
- data/vendor/redis-rb/profile.rb +22 -0
- data/vendor/redis-rb/redis-rb.gemspec +30 -0
- data/vendor/redis-rb/spec/redis_spec.rb +637 -0
- data/vendor/redis-rb/spec/spec_helper.rb +4 -0
- data/vendor/redis-rb/speed.rb +16 -0
- data/vendor/redis-rb/tasks/redis.tasks.rb +140 -0
- metadata +125 -0
data/test/rails_test.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class UseVanityController < ActionController::Base
|
4
|
+
attr_accessor :current_user
|
5
|
+
|
6
|
+
def index
|
7
|
+
render :text=>ab_test(:pie_or_cake)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Pages accessible to everyone, e.g. sign in, community search.
|
12
|
+
class UseVanityTest < ActionController::TestCase
|
13
|
+
tests UseVanityController
|
14
|
+
|
15
|
+
def setup
|
16
|
+
super
|
17
|
+
metric :sugar_high
|
18
|
+
new_ab_test :pie_or_cake do
|
19
|
+
metrics :sugar_high
|
20
|
+
end
|
21
|
+
UseVanityController.class_eval do
|
22
|
+
use_vanity :current_user
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_vanity_cookie_is_persistent
|
27
|
+
get :index
|
28
|
+
assert cookie = @response["Set-Cookie"].find { |c| c[/^vanity_id=/] }
|
29
|
+
assert expires = cookie[/vanity_id=[a-f0-9]{32}; path=\/; expires=(.*)(;|$)/, 1]
|
30
|
+
assert_in_delta Time.parse(expires), Time.now + 1.month, 1.minute
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_vanity_cookie_default_id
|
34
|
+
get :index
|
35
|
+
assert cookies['vanity_id'] =~ /^[a-f0-9]{32}$/
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_vanity_cookie_retains_id
|
39
|
+
@request.cookies['vanity_id'] = "from_last_time"
|
40
|
+
get :index
|
41
|
+
assert_equal "from_last_time", cookies['vanity_id']
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_vanity_identity_set_from_cookie
|
45
|
+
@request.cookies['vanity_id'] = "from_last_time"
|
46
|
+
get :index
|
47
|
+
assert_equal "from_last_time", @controller.send(:vanity_identity)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_vanity_identity_set_from_user
|
51
|
+
@controller.current_user = mock("user", :id=>"user_id")
|
52
|
+
get :index
|
53
|
+
assert_equal "user_id", @controller.send(:vanity_identity)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_vanity_identity_with_no_user_model
|
57
|
+
UseVanityController.class_eval do
|
58
|
+
use_vanity nil
|
59
|
+
end
|
60
|
+
@controller.current_user = Object.new
|
61
|
+
get :index
|
62
|
+
assert cookies['vanity_id'] =~ /^[a-f0-9]{32}$/
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_vanity_identity_set_with_block
|
66
|
+
UseVanityController.class_eval do
|
67
|
+
attr_accessor :project_id
|
68
|
+
use_vanity { |controller| controller.project_id }
|
69
|
+
end
|
70
|
+
@controller.project_id = "576"
|
71
|
+
get :index
|
72
|
+
assert_equal "576", @controller.send(:vanity_identity)
|
73
|
+
end
|
74
|
+
|
75
|
+
# query parameter filter
|
76
|
+
|
77
|
+
def test_redirects_and_loses_vanity_query_parameter
|
78
|
+
get :index, :foo=>"bar", :_vanity=>"567"
|
79
|
+
assert_redirected_to "/use_vanity?foo=bar"
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_sets_choices_from_vanity_query_parameter
|
83
|
+
first = experiment(:pie_or_cake).alternatives.first
|
84
|
+
# experiment(:pie_or_cake).fingerprint(first)
|
85
|
+
10.times do
|
86
|
+
@controller = nil ; setup_controller_request_and_response
|
87
|
+
get :index, :_vanity=>"aae9ff8081"
|
88
|
+
assert !experiment(:pie_or_cake).choose
|
89
|
+
assert experiment(:pie_or_cake).showing?(first)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_does_nothing_with_vanity_query_parameter_for_posts
|
94
|
+
first = experiment(:pie_or_cake).alternatives.first
|
95
|
+
post :index, :foo=>"bar", :_vanity=>"567"
|
96
|
+
assert_response :success
|
97
|
+
assert !experiment(:pie_or_cake).showing?(first)
|
98
|
+
end
|
99
|
+
|
100
|
+
def teardown
|
101
|
+
super
|
102
|
+
UseVanityController.send(:filter_chain).clear
|
103
|
+
end
|
104
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
$LOAD_PATH.delete_if { |path| path[/gems\/vanity-\d/] }
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
3
|
+
RAILS_ROOT = File.expand_path("..")
|
4
|
+
require "test/unit"
|
5
|
+
require "mocha"
|
6
|
+
require "action_controller"
|
7
|
+
require "action_controller/test_case"
|
8
|
+
require "active_record"
|
9
|
+
require "initializer"
|
10
|
+
Rails.configuration = Rails::Configuration.new
|
11
|
+
require "lib/vanity"
|
12
|
+
require "timecop"
|
13
|
+
|
14
|
+
|
15
|
+
if $VERBOSE
|
16
|
+
$logger = Logger.new(STDOUT)
|
17
|
+
$logger.level = Logger::DEBUG
|
18
|
+
else
|
19
|
+
$logger = Logger.new("/dev/null")
|
20
|
+
end
|
21
|
+
|
22
|
+
class Test::Unit::TestCase
|
23
|
+
|
24
|
+
def setup
|
25
|
+
FileUtils.mkpath "tmp/experiments/metrics"
|
26
|
+
new_playground
|
27
|
+
end
|
28
|
+
|
29
|
+
# Call this on teardown. It wipes put the playground and any state held in it
|
30
|
+
# (mostly experiments), resets vanity ID, and clears Redis of all experiments.
|
31
|
+
def nuke_playground
|
32
|
+
new_playground
|
33
|
+
Vanity.playground.redis.flushdb
|
34
|
+
end
|
35
|
+
|
36
|
+
# Call this if you need a new playground, e.g. to re-define the same experiment,
|
37
|
+
# or reload an experiment (saved by the previous playground).
|
38
|
+
def new_playground
|
39
|
+
Vanity.playground = Vanity::Playground.new(:logger=>$logger, :load_path=>"tmp/experiments", :db=>15)
|
40
|
+
Vanity.playground.mock! unless ENV["REDIS"]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Defines the specified metrics (one or more names). Returns metric, or array
|
44
|
+
# of metric (if more than one argument).
|
45
|
+
def metric(*names)
|
46
|
+
metrics = names.map do |name|
|
47
|
+
id = name.to_s.downcase.gsub(/\W+/, '_').to_sym
|
48
|
+
Vanity.playground.metrics[id] ||= Vanity::Metric.new(Vanity.playground, name)
|
49
|
+
end
|
50
|
+
names.size == 1 ? metrics.first : metrics
|
51
|
+
end
|
52
|
+
|
53
|
+
# Defines an A/B experiment.
|
54
|
+
def new_ab_test(name, &block)
|
55
|
+
id = name.to_s.downcase.gsub(/\W/, "_").to_sym
|
56
|
+
experiment = Vanity::Experiment::AbTest.new(Vanity.playground, id, name)
|
57
|
+
experiment.instance_eval &block
|
58
|
+
experiment.save
|
59
|
+
Vanity.playground.experiments[id] = experiment
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns named experiment.
|
63
|
+
def experiment(name)
|
64
|
+
Vanity.playground.experiment(name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def teardown
|
68
|
+
Vanity.context = nil
|
69
|
+
FileUtils.rm_rf "tmp"
|
70
|
+
Vanity.playground.redis.flushdb
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
ActionController::Routing::Routes.draw do |map|
|
76
|
+
map.connect ':controller/:action/:id'
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
ActiveRecord::Base.logger = $logger
|
81
|
+
ActiveRecord::Base.establish_connection :adapter=>"sqlite3", :database=>File.expand_path("database.sqlite")
|
82
|
+
# Call this to define aggregate functions not available in SQlite.
|
83
|
+
class ActiveRecord::Base
|
84
|
+
def self.aggregates
|
85
|
+
connection.raw_connection.create_aggregate("minimum", 1) do
|
86
|
+
step do |func, value|
|
87
|
+
func[:minimum] = value.to_i unless func[:minimum] && func[:minimum].to_i < value.to_i
|
88
|
+
end
|
89
|
+
finalize { |func| func.result = func[:minimum] }
|
90
|
+
end
|
91
|
+
|
92
|
+
connection.raw_connection.create_aggregate("maximum", 1) do
|
93
|
+
step do |func, value|
|
94
|
+
func[:maximum] = value.to_i unless func[:maximum] && func[:maximum].to_i > value.to_i
|
95
|
+
end
|
96
|
+
finalize { |func| func.result = func[:maximum] }
|
97
|
+
end
|
98
|
+
|
99
|
+
connection.raw_connection.create_aggregate("average", 1) do
|
100
|
+
step do |func, value|
|
101
|
+
func[:total] = func[:total].to_i + value.to_i
|
102
|
+
func[:count] = func[:count].to_i + 1
|
103
|
+
end
|
104
|
+
finalize { |func| func.result = func[:total].to_i / func[:count].to_i }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
class Array
|
111
|
+
# Not in Ruby 1.8.6.
|
112
|
+
unless method_defined?(:shuffle)
|
113
|
+
def shuffle
|
114
|
+
copy = clone
|
115
|
+
Array.new(size) { copy.delete_at(Kernel.rand(copy.size)) }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# Source: http://gist.github.com/25455
|
122
|
+
def context(*args, &block)
|
123
|
+
return super unless (name = args.first) && block
|
124
|
+
parent = Class === self ? self : (defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase)
|
125
|
+
klass = Class.new(parent) do
|
126
|
+
def self.test(name, &block)
|
127
|
+
define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
|
128
|
+
end
|
129
|
+
def self.xtest(*args) end
|
130
|
+
def self.setup(&block) define_method(:setup) { super() ; block.call } end
|
131
|
+
def self.teardown(&block) define_method(:teardown) { super() ; block.call } end
|
132
|
+
end
|
133
|
+
parent.const_set name.split(/\W+/).map(&:capitalize).join, klass
|
134
|
+
klass.class_eval &block
|
135
|
+
end
|
data/vanity.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "mikeg-vanity"
|
3
|
+
spec.version = "1.3.0"
|
4
|
+
spec.author = "Assaf Arkin"
|
5
|
+
spec.email = "assaf@labnotes.org"
|
6
|
+
spec.homepage = "http://vanity.labnotes.org"
|
7
|
+
spec.summary = "Experience Driven Development framework for Rails"
|
8
|
+
spec.description = "Mirror, mirror on the wall ..."
|
9
|
+
spec.post_install_message = "To get started run vanity --help"
|
10
|
+
|
11
|
+
spec.files = Dir["{bin,lib,vendor,test}/**/*", "CHANGELOG", "MIT-LICENSE", "README.rdoc", "vanity.gemspec"]
|
12
|
+
spec.executable = "vanity"
|
13
|
+
|
14
|
+
spec.has_rdoc = true
|
15
|
+
spec.extra_rdoc_files = "README.rdoc", "CHANGELOG"
|
16
|
+
spec.rdoc_options = "--title", "Vanity #{spec.version}", "--main", "README.rdoc",
|
17
|
+
"--webcvs", "http://github.com/assaf/#{spec.name}"
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ezra Zygmuntowicz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# redis-rb
|
2
|
+
|
3
|
+
A ruby client library for the redis key value storage system.
|
4
|
+
|
5
|
+
## Information about redis
|
6
|
+
|
7
|
+
Redis is a key value store with some interesting features:
|
8
|
+
1. It's fast.
|
9
|
+
2. Keys are strings but values can have types of "NONE", "STRING", "LIST", or "SET". List's can be atomically push'd, pop'd, lpush'd, lpop'd and indexed. This allows you to store things like lists of comments under one key while retaining the ability to append comments without reading and putting back the whole list.
|
10
|
+
|
11
|
+
See [redis on code.google.com](http://code.google.com/p/redis/wiki/README) for more information.
|
12
|
+
|
13
|
+
See the build on [RunCodeRun](http://runcoderun.com/rsanheim/redis-rb)
|
14
|
+
|
15
|
+
## Dependencies
|
16
|
+
|
17
|
+
1. rspec -
|
18
|
+
sudo gem install rspec
|
19
|
+
|
20
|
+
2. redis -
|
21
|
+
|
22
|
+
rake redis:install
|
23
|
+
|
24
|
+
2. dtach -
|
25
|
+
|
26
|
+
rake dtach:install
|
27
|
+
|
28
|
+
3. git - git is the new black.
|
29
|
+
|
30
|
+
## Setup
|
31
|
+
|
32
|
+
Use the tasks mentioned above (in Dependencies) to get your machine setup.
|
33
|
+
|
34
|
+
## Examples
|
35
|
+
|
36
|
+
Check the examples/ directory. *Note* you need to have redis-server running first.
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
require 'tasks/redis.tasks'
|
7
|
+
|
8
|
+
|
9
|
+
GEM = 'redis'
|
10
|
+
GEM_NAME = 'redis'
|
11
|
+
GEM_VERSION = '0.1'
|
12
|
+
AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark', 'Brian McKinney', 'Salvatore Sanfilippo', 'Luca Guidi']
|
13
|
+
EMAIL = "ez@engineyard.com"
|
14
|
+
HOMEPAGE = "http://github.com/ezmobius/redis-rb"
|
15
|
+
SUMMARY = "Ruby client library for redis key value storage server"
|
16
|
+
|
17
|
+
spec = Gem::Specification.new do |s|
|
18
|
+
s.name = GEM
|
19
|
+
s.version = GEM_VERSION
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.has_rdoc = true
|
22
|
+
s.extra_rdoc_files = ["LICENSE"]
|
23
|
+
s.summary = SUMMARY
|
24
|
+
s.description = s.summary
|
25
|
+
s.authors = AUTHORS
|
26
|
+
s.email = EMAIL
|
27
|
+
s.homepage = HOMEPAGE
|
28
|
+
s.add_dependency "rspec"
|
29
|
+
s.require_path = 'lib'
|
30
|
+
s.autorequire = GEM
|
31
|
+
s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("{lib,tasks,spec}/**/*")
|
32
|
+
end
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
desc "Run specs"
|
37
|
+
Spec::Rake::SpecTask.new do |t|
|
38
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
39
|
+
t.spec_opts = %w(-fs --color)
|
40
|
+
end
|
41
|
+
|
42
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
43
|
+
pkg.gem_spec = spec
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "install the gem locally"
|
47
|
+
task :install => [:package] do
|
48
|
+
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "create a gemspec file"
|
52
|
+
task :make_spec do
|
53
|
+
File.open("#{GEM}.gemspec", "w") do |file|
|
54
|
+
file.puts spec.to_ruby
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Run all examples with RCov"
|
59
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
60
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
61
|
+
t.rcov = true
|
62
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
$:.push File.join(File.dirname(__FILE__), 'lib')
|
3
|
+
require 'redis'
|
4
|
+
|
5
|
+
times = 20000
|
6
|
+
|
7
|
+
@r = Redis.new#(:debug => true)
|
8
|
+
@r['foo'] = "The first line we sent to the server is some text"
|
9
|
+
|
10
|
+
Benchmark.bmbm do |x|
|
11
|
+
x.report("set") do
|
12
|
+
20000.times do |i|
|
13
|
+
@r["set#{i}"] = "The first line we sent to the server is some text"; @r["foo#{i}"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
x.report("set (pipelined)") do
|
18
|
+
@r.pipelined do |pipeline|
|
19
|
+
20000.times do |i|
|
20
|
+
pipeline["set_pipelined#{i}"] = "The first line we sent to the server is some text"; @r["foo#{i}"]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
x.report("push+trim") do
|
26
|
+
20000.times do |i|
|
27
|
+
@r.push_head "push_trim#{i}", i
|
28
|
+
@r.list_trim "push_trim#{i}", 0, 30
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
x.report("push+trim (pipelined)") do
|
33
|
+
@r.pipelined do |pipeline|
|
34
|
+
20000.times do |i|
|
35
|
+
pipeline.push_head "push_trim_pipelined#{i}", i
|
36
|
+
pipeline.list_trim "push_trim_pipelined#{i}", 0, 30
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@r.keys('*').each do |k|
|
43
|
+
@r.delete k
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
def run_in_background(command)
|
4
|
+
fork { system command }
|
5
|
+
end
|
6
|
+
|
7
|
+
def with_all_segments(&block)
|
8
|
+
0.upto(9) do |segment_number|
|
9
|
+
block_size = 100000
|
10
|
+
start_index = segment_number * block_size
|
11
|
+
end_index = start_index + block_size - 1
|
12
|
+
block.call(start_index, end_index)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#with_all_segments do |start_index, end_index|
|
17
|
+
# puts "Initializing keys from #{start_index} to #{end_index}"
|
18
|
+
# system "ruby worker.rb initialize #{start_index} #{end_index} 0"
|
19
|
+
#end
|
20
|
+
|
21
|
+
with_all_segments do |start_index, end_index|
|
22
|
+
run_in_background "ruby worker.rb write #{start_index} #{end_index} 10"
|
23
|
+
run_in_background "ruby worker.rb read #{start_index} #{end_index} 1"
|
24
|
+
end
|