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

Consider promoting variants to something more complex? #7

Open
jejacks0n opened this issue Dec 17, 2022 · 0 comments
Open

Consider promoting variants to something more complex? #7

jejacks0n opened this issue Dec 17, 2022 · 0 comments
Labels
enhancement New feature or request feature request

Comments

@jejacks0n
Copy link
Owner

jejacks0n commented Dec 17, 2022

Variants are pretty simplistic, and don't understand anything about themselves. This is maybe a naive implementation and to be more flexible, variants could be expanded to be an object.

When a variant is registered, it's really being defined as two callback chains. One callback chain for the variant callbacks (e.g. before_variant(:red)), and one callback that's referred to as the variant steps (this is what can be overridden when running the experiment (e.g. experiment.on(:red) { "overridden red" }).

Because of this, variants are largely viewed as a name, and a "functionality." I use the term functionality here, because since it's just a callback, the functionality could be a proc/lambda, or a method, and can be overridden.

class MyExperiment < ActiveExperiment::Base
  control { }
  variant(:red) { }
end

MyExperiment.variants # => {:control=>:control_variant, :red=>:red_variant}

That's variant name => variant callback chain. I realized when adding the Unleash adapter, variants could have additional information/metadata associated with them, and it would be nice to have a place to put that information. For Unleash, variants have payload, and weights etc. ActiveExperiment shifts the variant weights and that logic off to the rollout, but I wonder if it's not a bad idea to introduce the concept of a variant being a Variant early.

So, what would that look like? Maybe pass some options through? Accept a class that inherits from a base Variant class? I want to explore this more, but some ideas:

class MyExperiment < ActiveExperiment::Base
  variant(:a_block) { "a block" } 
  variant(:a_method, :my_variant_method)

  # option 1?
  variant :an_instance, MyCustomVariant.new(payload: "foo") { "a variant block" }

  # option 2?
  variant :an_instance_via_proc, :my_variant_method, using: { MyCustomVariant.new(payload: "foo", name: :an_instance_via_proc) } 

  # option 3?
  variant(:with_options, options: { payload: "foo", weight: 30 }, using: MyCustomVariant)

  private

  def my_variant_method
    "my_variant_method"
  end
end

I wanted to open this issue and think on it. I think I like option 3.

@jejacks0n jejacks0n added enhancement New feature or request feature request labels Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feature request
Projects
None yet
Development

No branches or pull requests

1 participant