-
-
Notifications
You must be signed in to change notification settings - Fork 319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Flags! #4844
Feature Flags! #4844
Conversation
Problem is we are not getting a lot of feedback/bugreport until a release is publish An alternative to your idea would be to have an |
The idea is cool but yeah I'm wondering if we'd get much use out of it. Potentially it could also be evolved into something like an A/B test system and also cover the different WoW flavor checks. |
I don't think that's exactly what i'm imagining. it's more like, imagine if you had a big pull request that touched nearly every part of the codebase. such a big change naturally needs time to cook, but at the same time it's super annoying to have to solve merge conflicts all the time because normal maintenance keeps touching the same spots. It might be nice if changes could be committed more gradually & make the process smoother, meanwhile our LCD user is none the wiser. Once the feature is fully cooked, we would stop hiding it behind experimental status to "enable" the feature. I would be open to changing the criteria for if a build is experimental - perhaps we just want to block the release channel from seeing experimental changes without optin, i'm not sure. |
I agree with rivers that it would sometimes be nice if we could ship features behind an opt-in method. Though I do think changing how auras behave can easily lead to unintuitive behaviour when auras are shared between users that have it enabled or not. Even with such a flag available I probably couldn't use it for the progress source PR I have. Maybe it would have worked for the standby feature though. Now there are some questions on how to enable/disable the experimental mode:
which I think are both fine. I don't know about the method for user optin though, that is only enabled for the current session, so only temporarily. |
well, there's no way to disable experimental mode in a single session.😃 but, point taken; i was explicitly thinking about the case of "we are rolling out changes that involve a new export format, but we don't want to create a schism in our userbase", and a passive flag more than serves that purpose, since i doubt anyone is out there automatically exporting their auras |
Make it a generic feature flag system and we can try out different usecases? |
I whipped up a little feature flag system, which detects build type & can auto-enable named features based how WeakAuras was packaged. A feature can also declare itself to persist, and identify when/if an aura would require it to be enabled. to use, call |
That's pretty poggers as the youth would say |
|
||
---@param data auraData | ||
---@return boolean, table<string, boolean> | ||
function Features:AuraCanFunction(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably we'd communicate to the user if an aura they had required a disabled feature to function properly, but that sounds touchy to do & i figured we would cross that bridge when we got there
@@ -1170,6 +1182,10 @@ function Private.Login(initialTime, takeNewSnapshots) | |||
coroutine.yield(); | |||
end | |||
|
|||
|
|||
Private.Features:Hydrate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hydration of feature flags is timed so that it should be the first thing that happens on PLAYER_LOGIN (the bit of code above is a saved variables migration that would only happen if a user played for a brief period in 2019 but then quit until now). So, even if a user opts into a persisted feature, the code will still briefly think the feature is disabled until PLAYER_LOGIN.
@@ -35,6 +35,8 @@ ArchiveTypes\Repository.lua | |||
DefaultOptions.lua | |||
|
|||
# Core files | |||
SubscribableObject.lua | |||
Features.lua |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure exactly how to order the toc - since i'm using SubscribableObject obviously that needs to go before Features, but theoretically we could write feature flagged code at any point. So i just put it near the beginning, and we can muck with load order later if its a problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My biggest concern with this PR is about features that require a data migration
Should features with a migration have an optional "not reversible" flag
- then show an explicit warning to use that they should do a backup
- and/or trigger Archivist save point?
- and/or possibility for an optional reverse migration?
WeakAuras/WeakAuras.lua
Outdated
if Private.Features:Enabled(feature) then | ||
Private.Features:Disable(feature) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels wrong to me that /wa optin
is a toggle instead of having optin
& optout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to ff
, for 'flag feature'. I don't care one way or another, if ppl want to bikeshed that I'm happy to change it to whatever people prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with buds, enabling and disabling should be separate, otherwise telling users how to enable a feature is too complicated.
WeakAuras/Features.lua
Outdated
function Features:Enable(id) | ||
if self:Exists(id) and not self.__feats[id].enabled then | ||
self.__feats[id].enabled = true | ||
if self.__feats[id].persist then | ||
Private.db.features[id] = true | ||
end | ||
self.__feats[id].sub:Notify("ENABLED") | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
manually enable a feature may require a reload
if WeakAuras.IsLoginFinished() and self.__feats[id].enableBeforeLoginFinished then
-- called from /wa optin and feature needs to be enable earlier
ReloadUI()
else
self.__feats[id].sub:Notify("ENABLED")
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that depends on how code which depends on a feature is written, surely? I'd 'prefer' that code 'magically' works without having to reload ui if possible, if nothing else than for my personal convenience.
Otherwise looks reasonable. I'm pretty sure the disabling of features might not always be possible, but that can be adjusted once we have non-disabling features. And I'm a bit sceptical about whether auras requiring features is something we'll use, but imho with the two comments addressed it's ready to be merged. |
Last call for bikeshedding the syntax:
where |
@@ -35,6 +35,13 @@ jobs: | |||
- name: Update Build Date | |||
run: sed -i "s/@build-time@/`date +%Y%m%d%H%M%S`/" WeakAuras/Init.lua | |||
|
|||
- name: Flag Non-Experimental Build | |||
run: | | |||
sed -i -e "s/--@experimental@/--\[=====\[@experimental@/" WeakAuras/Init.lua \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 ='s, because bigwigs packager will use at most 4 ='s in its own @flag@
replacements
works for me |
WeakAuras/Features.lua
Outdated
@@ -84,7 +100,7 @@ function Features:Register(feature) | |||
feature.sub = Private.CreateSubscribableObject() | |||
for _, buildType in ipairs(feature.autoEnable or {}) do | |||
if WeakAuras.buildType == buildType then | |||
self:Enable(feature.id) | |||
self:Enable(feature.id, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cherry picked this from the undo pull request; otherwise it's annoying to disable a feature which auto-enables on your build type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this leads to the feature being enabled at first, before being disabled by hydrate.
I think a simpler approach is to require:
a) Registering a feature must be done before Hydrate
b) Hydrate decides on whether a feature is enabled/disabled, by whatever logic you decide.
.
That centralizes the logic on whether a feature starts off as enabled/disabled in one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it actually is simpler, but I see the appeal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworked Hydrate() to be a barrier between registering features and setting their enable state. It's an error to try to register after hydration, or to enable before.
d35a802
to
85ecde1
Compare
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Co-authored-by: Buds <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
Signed-off-by: Allen Faure <[email protected]>
320c1c7
to
d4d66af
Compare
im not sure if this is actually a useful idea or not, but (assuming i didn't screw up the yaml) this would provide us a way to get users to opt in to new features without explicitly making them available to everyone who enabled alpha mode but didn't understand what that means. That way, stuff like 'oops we changed the export format for WeakAuras and now 2% of our users can never share their auras until the next release' would be avoidable.
It's also possible that we just tell those people to get back on the standard release channel, idk.
Experimental mode is automatically enabled for any working copy, or for build artifacts on pull requests, otherwise the user must send the command
/wa optin
to enable it.Code can be feature-flagged by hiding it behind a
if WeakAuras.IsExperimental()
check.