Skip to content

Don't record assignment events for feature gates#69

Merged
jmileham merged 6 commits into
Betterment:masterfrom
jmileham:virtualize_gate_assignments
Apr 23, 2018
Merged

Don't record assignment events for feature gates#69
jmileham merged 6 commits into
Betterment:masterfrom
jmileham:virtualize_gate_assignments

Conversation

@jmileham

@jmileham jmileham commented Apr 12, 2018

Copy link
Copy Markdown
Member

Summary

Because feature gates are not used for analysis, there's no need to record anything but overrides for feature gates. This will vastly reduce the data that needs to change when deciding a feature gate split. It also will cause reweighting feature gates to affect clients in the field instantly unless they've been overridden.

Also explain the difference between experiments and gates to admins.

Other Information

This is compatible with all clients currently in the field, though behavior will change a bit. The chrome extension will reflect that no matter how many times you've experienced a gate, you are not assigned to a variant unless you assigned it via the extension or admin interface (or before this upgrade took place).

This should make slow rolling features much easier.

This is currently heuristically tagging splits as feature gates based on an _enabled suffix. The goal would be to later make creating feature gates (as distinct from experiments) a first class feature of the API so that you provision them differently, and for example, you only get true/false variants from a gate. But this is a very small step code-wise which should hopefully make a big difference to users of splits at scale that otherwise took a lot of dancing to slow roll.

/domain @Betterment/test_track_core
/domain @ceslami @klesse413 @betterzega or anybody else who has done big slow roll releases who has opinions.

Because feature gates are not used for analysis, there's no need to
record anything but overrides for feature gates. This will vastly reduce
the data that needs to change when deciding a feature gate split. It
also will cause reweighting feature gates to affect clients in the field
instantly unless they've been overridden.

Also explain the difference between experiments and gates to admins.
@nanda-prbot

Copy link
Copy Markdown

@jmileham needs to request domain and platform reviewers, or explicitly opt out, e.g.:

/no-platform

@jmileham

Copy link
Copy Markdown
Member Author

/platform @klesse413 @aburgel @samandmoore @smudge @effron

@nanda-prbot

Copy link
Copy Markdown

Needs somebody from @Betterment/test_track_core to claim domain review
Needs somebody from @ceslami, @klesse413, and @betterzega to claim domain review
Needs somebody from @klesse413, @aburgel, @samandmoore, @smudge, and @effron to claim platform review

Use the shovel operator to claim, e.g.:

@myname << domain && platform

@@ -0,0 +1,6 @@
class AddSplitFeatureGate < ActiveRecord::Migration[5.0]
def change
add_column :splits, :feature_gate, :boolean, default: false, null: false

@jmileham jmileham Apr 12, 2018

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a high read throughput table but very small number of rows and there are effectively no long-running transactions on this service. My hope is this doesn't cause issues on deploy. :) /cc @Betterment/data for commentary.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 not sure what our tt deploy pattern is, maybe we want to deploy to stage first and watch the migration?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won’t do much for lock contention confidence because of the vastly different load levels but yeah. Will do this and the other off hours unless data says no.

end

def feature_gate?
name.end_with?("_enabled")

@betterzega betterzega Apr 12, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we want something more explicit on the split to tag the type of split coming from the client?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm yeah, long term i would think probably something more explicit (although shorter term this gets the job done). we use this naming convention, but that's not to say others necessarily do. do we recommend it in documentation anywhere?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so but it might just be in a blog post or something.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, here's the blog post by the man himself @joejansen

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆒 no external documentation though right? seems worth highlighting for other users that they'll get this functionality based on naming convention

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added to readme

<% if @split.feature_gate? %>
<p>
<a id="gate_population"></a>
* Feature gates do not track assignment events and population reflects only visitors assigned to specific variants.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 can we make this even more explicit, maybe only visitors assigned to specific variants via the chrome extension or admin tool or something to make clear that if 10 Betterment employees have it on it will show population 10 even if the weight is 20% true and thousands fo people have seen the true experience

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

context: context
)
unless split.feature_gate?
ArbitraryAssignmentCreation.create!(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chatted offline, @jmileham pointed out that if product still wants to know how many people have seen the enabled experience (e.g. we've turned the feature flag on for 20% of people and want to gauge if there are any blocking bugs) we can query redshift's customer_prod.split_assigned table because segment will still track assignment events 💯

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent. for debugging purposes i think there is value in continuing to fire the SplitAssigned event to the analytics client that is configured by the client code.

@jmileham

Copy link
Copy Markdown
Member Author

/domain @joejansen for analytics backend impact (that makes 3 domain reviews, I don't wanna jump the gun on this)

@nanda-prbot

Copy link
Copy Markdown

Needs somebody from @Betterment/test_track_core to claim domain review
Needs somebody from @ceslami, @klesse413, and @betterzega to claim domain review
Needs somebody from @klesse413, @aburgel, @samandmoore, @smudge, and @effron to claim platform review
Needs somebody from @joejansen to claim domain review

Use the shovel operator to claim, e.g.:

@myname << domain && platform

@asullivan210

Copy link
Copy Markdown

nanda?

@nanda-prbot

Copy link
Copy Markdown

Needs somebody from @Betterment/test_track_core to claim domain review
Needs somebody from @ceslami, @klesse413, and @betterzega to claim domain review
Needs somebody from @klesse413, @aburgel, @samandmoore, @smudge, and @effron to claim platform review
Needs somebody from @joejansen to claim domain review

Use the shovel operator to claim, e.g.:

@myname << domain && platform

@asullivan210

Copy link
Copy Markdown

<<domain

@nanda-prbot

Copy link
Copy Markdown

Needs somebody from @ceslami, @klesse413, and @betterzega to claim domain review
Needs somebody from @klesse413, @aburgel, @samandmoore, @smudge, and @effron to claim platform review
Needs somebody from @joejansen to claim domain review

Use the shovel operator to claim, e.g.:

@myname << domain && platform

<% else %>
<p>
This split is an experiment. Changing weights will have no immediate effect
on the behavior of visitors who have already experienced a variant this

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a variant of this split?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️

@jmileham

Copy link
Copy Markdown
Member Author

So in the interest of transparency, this will result in duplicate assignment events per visitor for gates experienced more than once. Normally a client retrieves all assignments from TT before displaying any content to the visitor, and if an assignment for a given split exists, it'll just render it. But since the server will have no record of an assignment, every single time a customer experiences a gate, another assignment event will be triggered. This will both hit segment and TT. So it'll increase event volume a bit for a given level of traffic, and if we cared about the event data (which we do not) it would be misleadingly noisey, with duplicate events happening a fair amount.

In future iterations of client libs we can phase out sending assignment events for feature gates and focus on only sending experience events, which we'd want to send each time.

@samandmoore

Copy link
Copy Markdown
Member

@jmileham can you spec that out as a GitHub issue in one of the clients like the ruby one? And then link it up in a corresponding issue in the js client? It’d be great to have an record of that.

@jmileham

Copy link
Copy Markdown
Member Author

Another side effect of this strategy is that signing in from a new computer or any other activity that ends up swapping your visitor ID will likely cause you to end up in a different variant for a given feature gate than you would have as your anonymous visitor, even if you've never experienced that feature gate before. Normal visitor supersession logic would've applied the variant from your anonymous visitor to your authenticated visitor if the authenticated visitor had no such assignment, but in this case, you will simply get a deterministic assignment appropriate to your visitor ID each time.

This isn't a big change for most folks. Once you've signed into a device, if you're the only user of the device, your visitor ID will remain constant between sessions so you'll have a consistent experience. And if multiple users use a device, they will have already encountered the same issue as they swap back and forth between their visitor IDs upon login.

Comment thread README.md
customer with a stable variant given a constant split weighting, but
probablistically increase the size of the population experiencing the
the `true` variant as the split weightings are increased via the admin
panel, giving an admin full control over the feature's release.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klesse413 - I wrote out the definitions and behaviors of experiments and feature gates in the readme. I'm hypothetically calling this version 1.2. It seems big enough to be worth a point release, but I kinda want to save 2.0 for the version that enables a different migration DSL API contract for defining experiments vs gates, and does things like force them to have conventional names and variants.

Comment thread README.md Outdated
As of TestTrack version 1.2, splits with names ending in the `_enabled`
suffix will be treated as feature gates. Feature gates differ from
experiments in that they are not intended to be used for analysis, and
therefor it is not important that the user remain in the same variant

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

therefor 👮

Comment thread README.md
customer with a stable variant given a constant split weighting, but
probablistically increase the size of the population experiencing the
the `true` variant as the split weightings are increased via the admin
panel, giving an admin full control over the feature's release.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't we only store the assignment if a customer is explicitly assigned via the admin panel? i.e. if we just increase the true weighting on incremental rollout, couldn't a customer randomly experience the true version and then come back and randomly experience the false version? so we have to incrementally release by explicit assignment of customer ids? or am i missing something?

@jmileham jmileham Apr 13, 2018

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The algo works something like this:

truncate_to_integer_and_mod_100(sha1(visitor_id + split_name))

we then sort the variants alphabetically and then assign them ranges making up the numbers between 0 and 99. You experience the variant that your number buckets to.

So as we ratchet up or down, the same users for a given split will be rolled out to and rolled back from in deterministic, pseudorandom order per split.

That said, I probably shouldn't use the word population in this definition in a way that differs from the population in the admin - none of these visitors will show up in the population in the admin, because they won't have any concrete assignments.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this would work horribly if you had more than two variants in a gate as the middle variant would slide through the population, but what kind of gate has more than two sides? this is why we wanna formalize the API for making gates.)

because we use it in the admin to mean "recorded assignees of experiments."
@jmileham

Copy link
Copy Markdown
Member Author

Alright, I'm being needy.

@klesse413 << domain platform - you can't comment this much without providing a review :)
@joejansen << domain

Would love to land this because it shouldn't be disruptive and will make feature rollouts Much Easier.

@nanda-prbot

Copy link
Copy Markdown

Needs @asullivan210 to provide domain review
Needs @klesse413 to provide platform review
Needs @klesse413 to provide domain review
Needs @joejansen to provide domain review

When you finish a round of review, be sure to say you've finished or sign off on the PR, e.g.:

TAFN or DomainLGTM

If you're too busy to review, unclaim the PR, e.g.:

@myname >> domain

@joejansen

Copy link
Copy Markdown

domainlgtm

@nanda-prbot

Copy link
Copy Markdown

Needs @asullivan210 to provide domain review
Needs @klesse413 to provide platform review
Needs @klesse413 to provide domain review

When you finish a round of review, be sure to say you've finished or sign off on the PR, e.g.:

TAFN or DomainLGTM

If you're too busy to review, unclaim the PR, e.g.:

@myname >> domain

<div class="InfoCard-titleContainer">
<h4>Variant Details</h4>
<%= link_to "Edit", new_admin_split_split_config_path(split), class: 'change-weights-link' %>
<%= link_to "Change Weights", new_admin_split_split_config_path(split), class: 'change-weights-link' %>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌 👍 for more descriptive links. ive always been confused by the 5 different "edit" links on the split page - when I want to assign a user I never know which one to click 😂

@klesse413

Copy link
Copy Markdown

domainlgtm platformlgtm 🙌 my team is super excited about this!

@nanda-prbot

Copy link
Copy Markdown

Needs @asullivan210 to provide domain review

When you finish a round of review, be sure to say you've finished or sign off on the PR, e.g.:

TAFN or DomainLGTM

If you're too busy to review, unclaim the PR, e.g.:

@myname >> domain

@asullivan210

Copy link
Copy Markdown

domainLGTM

@nanda-prbot

Copy link
Copy Markdown

Approved! 🙆‍♀️ 🙏 🙌

@jmileham
jmileham merged commit 60cb87f into Betterment:master Apr 23, 2018
@jmileham
jmileham deleted the virtualize_gate_assignments branch April 23, 2018 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants