Introducing a quick and dirty fix for abtests/admin (#17982)
This is a "quick and dirty" hack. Do I like it? No. Do I want to delve
into further debugging/refactoring of [a 72 line method][1]? Not at the
moment. There are a few pathways forward, but for now, this is the
pathway to hopefully give us insight into the
**Why will this likely address the issue?**
Prior to this commit, for an experiment we would render each of the
goals (anywhere from 8 to 11); each of which would require 2 expensive
queries; which means about 16 expensive queries.
After this commit, the experiment page has none of those expensive
queries; instead each goal now runs the 2 expensive queries.
The hope is that this will help us show the results (albeit on multiple
pages) while coming in under the response time out handlers we have in
place.
**Why no tests?**
Ugh; I know right?!? I'm beginning to ask that myself. But for now,
because this is only visible to tech_admins, the consequences of
breaking are limited. In otherwords, this is not a customer facing
feature, so it can be a bit less robust in it's testing. At least
that's the rationalization I'm establishing.
Further, local tests would not reveal the production environment
complications of large data sets. The aforementioned expensive queries
are blisteringly fast on my local machine...in part because I don't much
field_test experiment data.
Closes forem/forem#17981
Related to:
- forem/forem#17895
- forem/forem#17869
[1]:ab2d7d29d0/lib/field_test/experiment.rb (L98-L160)
This commit is contained in:
parent
ec55329a3a
commit
b8533172e3
4 changed files with 70 additions and 48 deletions
|
|
@ -12,5 +12,15 @@ module FieldTest
|
|||
rescue FieldTest::ExperimentNotFound
|
||||
raise ActionController::RoutingError, "Experiment not found"
|
||||
end
|
||||
|
||||
def goal
|
||||
@experiment = FieldTest::Experiment.find(params[:experiment_id])
|
||||
@goal = params.fetch(:goal)
|
||||
unless @experiment.goals.include?(@goal)
|
||||
raise ActionController::RoutingError, "Experiment's goal not found"
|
||||
end
|
||||
rescue FieldTest::ExperimentNotFound
|
||||
raise ActionController::RoutingError, "Experiment not found"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
52
app/views/field_test/experiments/goal.html.erb
Normal file
52
app/views/field_test/experiments/goal.html.erb
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<style>
|
||||
details details { padding: 1em 0 0 1.5em; }
|
||||
</style>
|
||||
<% experiment = @experiment %>
|
||||
<h1><%= experiment.name %><% unless experiment.active? %> <small class="closed">Completed</small><% end %></h1>
|
||||
<%# NOTE: The root_path is the Rails's engine root path, not the application's root path (e.g. "/") %>
|
||||
<p><%= link_to "Back to Experiments", FieldTest.railtie_routes_url_helpers.experiment_path(experiment.id) %></p>
|
||||
|
||||
<h2><%= @goal.titleize %></h2>
|
||||
<% results = experiment.results(goal: @goal) %>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variant</th>
|
||||
<th style="width: 20%;">Participants</th>
|
||||
<th style="width: 20%;">Conversions</th>
|
||||
<th style="width: 20%;">Conversion Rate</th>
|
||||
<th style="width: 20%;">Prob Winning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% results.each do |variant, result| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= variant %>
|
||||
<% if variant == experiment.winner %>
|
||||
<span class="check">✓</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= result[:participated] %></td>
|
||||
<td><%= result[:converted] %></td>
|
||||
<td>
|
||||
<% if result[:conversion_rate] %>
|
||||
<%= (100.0 * result[:conversion_rate]).round(FieldTest.precision) %>%
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if result[:prob_winning] %>
|
||||
<% if result[:prob_winning] < 0.01 %>
|
||||
< 1%
|
||||
<% else %>
|
||||
<%= (100.0 * result[:prob_winning]).round(FieldTest.precision) %>%
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -14,55 +14,14 @@
|
|||
|
||||
<details<%= " open" if experiment.active? %>>
|
||||
<summary>Goals for <%= experiment.name %></summary>
|
||||
<% experiment.goals.each do |goal| %>
|
||||
<% results = experiment.results(goal: goal) %>
|
||||
|
||||
<% if experiment.multiple_goals? %>
|
||||
<h2><%= goal.titleize %></h2>
|
||||
<ul>
|
||||
<% experiment.goals.each do |goal| %>
|
||||
<%# I would love to use a route/path, but the router at runtime was
|
||||
not recognizing it. The `rails routes` would show it, but not
|
||||
the view handler. %>
|
||||
<li><%= link_to goal.titleize, "./#{experiment.id}/#{goal}" %></li>
|
||||
<% end %>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variant</th>
|
||||
<th style="width: 20%;">Participants</th>
|
||||
<th style="width: 20%;">Conversions</th>
|
||||
<th style="width: 20%;">Conversion Rate</th>
|
||||
<th style="width: 20%;">Prob Winning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% results.each do |variant, result| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= variant %>
|
||||
<% if variant == experiment.winner %>
|
||||
<span class="check">✓</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= result[:participated] %></td>
|
||||
<td><%= result[:converted] %></td>
|
||||
<td>
|
||||
<% if result[:conversion_rate] %>
|
||||
<%= (100.0 * result[:conversion_rate]).round(FieldTest.precision) %>%
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if result[:prob_winning] %>
|
||||
<% if result[:prob_winning] < 0.01 %>
|
||||
< 1%
|
||||
<% else %>
|
||||
<%= (100.0 * result[:prob_winning]).round(FieldTest.precision) %>%
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<% if experiment.id.start_with?("feed_strategy") %>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace :admin do
|
|||
|
||||
mount Sidekiq::Web => "sidekiq"
|
||||
mount FieldTest::Engine, at: "abtests"
|
||||
get "abtests/experiments/:experiment_id/:goal", to: "/field_test/experiments#goal"
|
||||
|
||||
flipper_ui = Flipper::UI.app(Flipper,
|
||||
{ rack_protection: { except: %i[authenticity_token form_token json_csrf
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue