Skip to content
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

feat(feature-flags): Enable local evaluation of flags #68

Merged
merged 22 commits into from
Jul 29, 2022
Merged

Conversation

neilkakkar
Copy link
Contributor

@neilkakkar neilkakkar commented Jul 25, 2022

Following spec from PostHog/posthog#10459

The PR isn't really that big, ~3,000 LoC are tests, 2,000 of which are autogenerated consistency tests.

(but still big enough, sigh). Wanted to figure out exactly what all we need for the new library to be feature complete, and use this as a template for other libraries to follow.

@EDsCODE
Copy link
Member

EDsCODE commented Jul 25, 2022

Update:

  • Applied black and isort so the line diffs exploded but it's just because of the result set in the test
  • Adjust simple flag handling so that existing tests still pass. Feel free to change this as necessary. A few tests are still failing here because of this
  • Adjusted return of "get_feature_flag" so that it still returns variants and not just booleans
  • Added group property evaluation
  • Added tests for person property eval and group property eval

@neilkakkar
Copy link
Contributor Author

Thanks!

I was planning to not have any deprecated options in the library, since we control the API which returns flag definitions, and we can transform all deprecated ones into new ones. Effectively, I want to deprecate is_simple_flag evaluation here, since and only have one code path that's exactly the same as the main logic on our servers.

@neilkakkar
Copy link
Contributor Author

That would probs imply a major version update, so self-hosted know not to upgrade unless they're on PostHog version 1.38, but I think that's a good trade-off to make, since it means a little less code in every client library, and a clean cut w.r.t the API endpoints used to support local eval. (see main PostHog PR, very much WIP: PostHog/posthog#10957 )

flag_filters = feature_flag.get("filters") or {}
aggregation_group_type_index = flag_filters.get("aggregation_group_type_index")
if aggregation_group_type_index is not None:
focused_group_properties = group_properties[
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is tricky. We should hash out how we expect users to add properties here.

I think what you're doing makes sense, specially when different groups can have the same name property. However at the same time, feature flags support a single group at a time, so we'd expect only properties from a single group per call..

This is more future proof, but also a bit annoying for current user needs.

Copy link
Member

Choose a reason for hiding this comment

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

EIther works for me. When only one group is in focus, how does this function know which group is being used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

aggregation_group_type_index ? Not sure I get the question

Copy link
Member

Choose a reason for hiding this comment

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

Oh, so upon calling posthog.get_feature_flag() you're assumed to already know what group type the flag in question is, so you only pass in the group properties related to that group?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah pretty much, since they're the ones who defined the flag

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, thought about this a bit more, and I think your format makes sense, since we'll want to send these properties to /decide as well, when we do fallback, so that these props can be overridden.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And /decide evaluates multiple flags, and we don't know which of those have which groups

for consumer in client.consumers:
self.assertEqual(consumer.timeout, 15)

@mock.patch("posthog.client.Poller")
@mock.patch("posthog.client.get")
def test_load_feature_flags(self, patch_get, patch_poll):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

these moved to test_feature_flags.py

@neilkakkar
Copy link
Contributor Author

A better handle on what the tests are doing: PostHog/posthog#10459 (comment) (scroll to the bottom) - I've added tests we'd need in common between all libraries

@neilkakkar neilkakkar marked this pull request as ready for review July 28, 2022 12:11
@neilkakkar neilkakkar requested a review from liyiy July 28, 2022 12:23
@neilkakkar neilkakkar requested a review from EDsCODE July 28, 2022 12:29
Copy link
Member

@EDsCODE EDsCODE left a comment

Choose a reason for hiding this comment

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

great work!

@neilkakkar neilkakkar merged commit 2c6b675 into master Jul 29, 2022
@neilkakkar neilkakkar deleted the local-flags branch July 29, 2022 13:10

@mock.patch("posthog.client.decide")
@mock.patch("posthog.client.get")
def test_feature_enabled_simple(self, patch_get, patch_decide):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this and following tests were copied over from the client, so not necessary to write again in every other lib (these libs should have their own old tests 🤷).

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.

2 participants