trailguide 0.1.12 → 0.1.13
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/app/controllers/trail_guide/admin/experiments_controller.rb +5 -0
- data/app/views/trail_guide/admin/experiments/_experiment.html.erb +4 -2
- data/config/routes.rb +1 -0
- data/lib/trail_guide/experiment.rb +31 -6
- data/lib/trail_guide/experiment_config.rb +5 -0
- data/lib/trail_guide/participant.rb +4 -2
- data/lib/trail_guide/version.rb +1 -1
- data/lib/trailguide.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c626f06613b7702e01f9c19ef77f6f77e022f0c1280cc13205e46a95bc3ff548
|
4
|
+
data.tar.gz: a91f183473695792a9c067d3ca8e59d91177b0bf97bc1ae29d34c976ba177760
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0952f9bdb7840f6e201f78a0eb46bfcfe296bcfb115db735062923a8ae9e670c194e7c244225471a1484eaa4649a80f0612061fa4c1c81e7fa0c4824e89ddb3
|
7
|
+
data.tar.gz: 5432d3d30169caa958a344f99d732f389cd1ed23c052a41a0f86a6ef1b39ad2fac7e337dc81d586875d190d3ef9f2236d3abf81268f8ee3714458582409a86b7
|
@@ -23,6 +23,11 @@ module TrailGuide
|
|
23
23
|
redirect_to :back rescue redirect_to trail_guide_admin.experiments_path
|
24
24
|
end
|
25
25
|
|
26
|
+
def resume
|
27
|
+
experiment.resume!
|
28
|
+
redirect_to :back rescue redirect_to trail_guide_admin.experiments_path
|
29
|
+
end
|
30
|
+
|
26
31
|
def restart
|
27
32
|
experiment.reset! && experiment.start!
|
28
33
|
redirect_to :back rescue redirect_to trail_guide_admin.experiments_path
|
@@ -10,13 +10,15 @@
|
|
10
10
|
</h3>
|
11
11
|
</div>
|
12
12
|
<div class="col-sm-12 col-md-6 col-lg-4 text-right">
|
13
|
-
<% if experiment.
|
13
|
+
<% if experiment.running? %>
|
14
14
|
<%= link_to "stop", trail_guide_admin.stop_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-warning', method: :put %>
|
15
15
|
<%= link_to "restart", trail_guide_admin.restart_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-danger',method: :put %>
|
16
|
+
<% elsif experiment.started? %>
|
17
|
+
<%= link_to "resume", trail_guide_admin.resume_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-primary',method: :put %>
|
16
18
|
<% else %>
|
17
19
|
<%= link_to "start", trail_guide_admin.start_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-success',method: :put %>
|
18
20
|
<% end %>
|
19
|
-
<%= link_to "reset", trail_guide_admin.reset_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-danger',method: :put %>
|
21
|
+
<%= link_to "reset", trail_guide_admin.reset_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-outline-danger',method: :put %>
|
20
22
|
</div>
|
21
23
|
</div>
|
22
24
|
|
data/config/routes.rb
CHANGED
@@ -19,6 +19,7 @@ if defined?(TrailGuide::Admin::Engine)
|
|
19
19
|
match :start, via: [:put, :post, :get]
|
20
20
|
match :stop, via: [:put, :post, :get]
|
21
21
|
match :reset, via: [:put, :post, :get]
|
22
|
+
match :resume, via: [:put, :post, :get]
|
22
23
|
match :restart, via: [:put, :post, :get]
|
23
24
|
match :winner, via: [:put, :post, :get], path: 'winner/:variant'
|
24
25
|
end
|
@@ -56,26 +56,50 @@ module TrailGuide
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def stop!
|
59
|
-
return false unless
|
60
|
-
stopped = TrailGuide.redis.
|
59
|
+
return false unless running?
|
60
|
+
stopped = TrailGuide.redis.hset(storage_key, 'stopped_at', Time.now.to_i)
|
61
61
|
run_callbacks(:on_stop)
|
62
62
|
stopped
|
63
63
|
end
|
64
64
|
|
65
|
+
def resume!
|
66
|
+
return false unless started? && stopped?
|
67
|
+
restarted = TrailGuide.redis.hdel(storage_key, 'stopped_at')
|
68
|
+
run_callbacks(:on_resume)
|
69
|
+
restarted
|
70
|
+
end
|
71
|
+
|
65
72
|
def started_at
|
66
73
|
started = TrailGuide.redis.hget(storage_key, 'started_at')
|
67
74
|
return Time.at(started.to_i) if started
|
68
75
|
end
|
69
76
|
|
77
|
+
def stopped_at
|
78
|
+
stopped = TrailGuide.redis.hget(storage_key, 'stopped_at')
|
79
|
+
return Time.at(stopped.to_i) if stopped
|
80
|
+
end
|
81
|
+
|
70
82
|
def started?
|
71
83
|
!!started_at
|
72
84
|
end
|
73
85
|
|
86
|
+
def stopped?
|
87
|
+
!!stopped_at
|
88
|
+
end
|
89
|
+
|
90
|
+
def running?
|
91
|
+
started? && !stopped?
|
92
|
+
end
|
93
|
+
|
74
94
|
def declare_winner!(variant)
|
75
95
|
variant = variant.name if variant.is_a?(Variant)
|
76
96
|
TrailGuide.redis.hset(storage_key, 'winner', variant.to_s.underscore)
|
77
97
|
end
|
78
98
|
|
99
|
+
def clear_winner!
|
100
|
+
TrailGuide.redis.hdel(storage_key, 'winner')
|
101
|
+
end
|
102
|
+
|
79
103
|
def winner
|
80
104
|
winner = TrailGuide.redis.hget(storage_key, 'winner')
|
81
105
|
return variants.find { |var| var == winner } if winner
|
@@ -133,9 +157,9 @@ module TrailGuide
|
|
133
157
|
|
134
158
|
attr_reader :participant
|
135
159
|
delegate :configuration, :experiment_name, :variants, :control, :funnels,
|
136
|
-
:storage_key, :started?, :started_at, :start!, :resettable?,
|
137
|
-
:winner, :allow_multiple_conversions?, :allow_multiple_goals?,
|
138
|
-
to: :class
|
160
|
+
:storage_key, :running?, :started?, :started_at, :start!, :resettable?,
|
161
|
+
:winner?, :winner, :allow_multiple_conversions?, :allow_multiple_goals?,
|
162
|
+
:callbacks, to: :class
|
139
163
|
|
140
164
|
def initialize(participant)
|
141
165
|
@participant = participant
|
@@ -158,12 +182,13 @@ module TrailGuide
|
|
158
182
|
return control if TrailGuide.configuration.disabled
|
159
183
|
if override.present?
|
160
184
|
variant = variants.find { |var| var == override }
|
161
|
-
return variant unless configuration.track_override &&
|
185
|
+
return variant unless configuration.track_override && running?
|
162
186
|
else
|
163
187
|
return winner if winner?
|
164
188
|
return control if excluded
|
165
189
|
return control if !started? && configuration.start_manually
|
166
190
|
start! unless started?
|
191
|
+
return control unless running?
|
167
192
|
return variants.find { |var| var == participant[storage_key] } if participating?
|
168
193
|
return control unless TrailGuide.configuration.allow_multiple_experiments == true || !participant.participating_in_active_experiments?(TrailGuide.configuration.allow_multiple_experiments == false)
|
169
194
|
|
@@ -23,6 +23,7 @@ module TrailGuide
|
|
23
23
|
on_convert: [TrailGuide.configuration.on_experiment_convert].flatten.compact,
|
24
24
|
on_start: [TrailGuide.configuration.on_experiment_start].flatten.compact,
|
25
25
|
on_stop: [TrailGuide.configuration.on_experiment_stop].flatten.compact,
|
26
|
+
on_resume: [TrailGuide.configuration.on_experiment_resume].flatten.compact,
|
26
27
|
on_reset: [TrailGuide.configuration.on_experiment_reset].flatten.compact,
|
27
28
|
on_delete: [TrailGuide.configuration.on_experiment_delete].flatten.compact,
|
28
29
|
}
|
@@ -121,6 +122,10 @@ module TrailGuide
|
|
121
122
|
callbacks[:on_stop] << (meth || block)
|
122
123
|
end
|
123
124
|
|
125
|
+
def on_resume(meth=nil, &block)
|
126
|
+
callbacks[:on_resume] << (meth || block)
|
127
|
+
end
|
128
|
+
|
124
129
|
def on_reset(meth=nil, &block)
|
125
130
|
callbacks[:on_reset] << (meth || block)
|
126
131
|
end
|
@@ -30,6 +30,7 @@ module TrailGuide
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def participating?(experiment, include_control=true)
|
33
|
+
return false unless experiment.started?
|
33
34
|
return false unless adapter.key?(experiment.storage_key)
|
34
35
|
varname = adapter[experiment.storage_key]
|
35
36
|
variant = experiment.variants.find { |var| var == varname }
|
@@ -41,6 +42,7 @@ module TrailGuide
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def converted?(experiment, checkpoint=nil)
|
45
|
+
return false unless experiment.started?
|
44
46
|
if experiment.funnels.empty?
|
45
47
|
raise InvalidGoalError, "You provided the checkpoint `#{checkpoint}` but the experiment `#{experiment.experiment_name}` does not have any goals defined." unless checkpoint.nil?
|
46
48
|
storage_key = "#{experiment.storage_key}:converted"
|
@@ -92,7 +94,7 @@ module TrailGuide
|
|
92
94
|
return false if adapter.keys.empty?
|
93
95
|
adapter.keys.map { |key| key.to_s.split(":").first.to_sym }.uniq.map do |key|
|
94
96
|
experiment = TrailGuide.catalog.find(key)
|
95
|
-
next unless experiment && experiment.
|
97
|
+
next unless experiment && experiment.running? && participating?(experiment, include_control)
|
96
98
|
[ experiment.experiment_name, adapter[experiment.storage_key] ]
|
97
99
|
end.compact.to_h
|
98
100
|
end
|
@@ -103,7 +105,7 @@ module TrailGuide
|
|
103
105
|
adapter.keys.any? do |key|
|
104
106
|
experiment_name = key.to_s.split(":").first.to_sym
|
105
107
|
experiment = TrailGuide.catalog.find(experiment_name)
|
106
|
-
experiment && experiment.
|
108
|
+
experiment && experiment.running? && participating?(experiment, include_control)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
end
|
data/lib/trail_guide/version.rb
CHANGED
data/lib/trailguide.rb
CHANGED
@@ -33,6 +33,7 @@ module TrailGuide
|
|
33
33
|
|
34
34
|
config.on_experiment_start = nil # -> (experiment) { ... }
|
35
35
|
config.on_experiment_stop = nil # -> (experiment) { ... }
|
36
|
+
config.on_experiment_resume = nil # -> (experiment) { ... }
|
36
37
|
config.on_experiment_reset = nil # -> (experiment) { ... }
|
37
38
|
config.on_experiment_delete = nil # -> (experiment) { ... }
|
38
39
|
|