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

Flipper Redis Adapter ignoring configuration block sometimes #856

Open
micahtessler opened this issue Mar 6, 2024 · 5 comments
Open

Flipper Redis Adapter ignoring configuration block sometimes #856

micahtessler opened this issue Mar 6, 2024 · 5 comments

Comments

@micahtessler
Copy link

When upgrading from flipper 1.1.2 to flipper 1.2.2 the behavior of the redis adapter changed.

Sometimes it initializes from my configuration block:

        ::Flipper.configure do |config|
          config.adapter do
            ::Flipper::Adapters::Redis.new(
              ::Redis.new(:url => configuration.feature_flag_redis)
          end
        end

Other times, it ignores that block and uses the block at the bottom of the flipper redis adapter

Flipper.configure do |config|

I edited my local copies of the gems to dump the stack to trace the problem (so some line numbers don't 100% line up).

When I start my rails application in puma, I see the redis adapter initializing 3 times.
Once with the adapter constructed in my code and twice with the adapter constructed from the flipper redis adapter gem

If I make a request that gets the adapter I initialized, the page renders.
If I make a request with the adapter initialized by the redis adapter, the page errors because the redis URL is incorrect.

The stack trace of the good adapter (the first one that intializes)

.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:28:in `backtrace'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:28:in `initialize'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/feature-flag-0.13.2/lib/feature/flag/initializer/initializer.rb:50:in `new'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/feature-flag-0.13.2/lib/feature/flag/initializer/initializer.rb:50:in `flipper_adapter'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/feature-flag-0.13.2/lib/feature/flag/initializer/initializer.rb:31:in `block (2 levels) in configure_flipper'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/adapter_builder.rb:41:in `to_adapter'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/configuration.rb:29:in `adapter'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/engine.rb:54:in `block (3 levels) in <class:Engine>'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/configuration.rb:65:in `default'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper.rb:46:in `instance'
.rbenv/versions/3.1.4/lib/ruby/3.1.0/forwardable.rb:232:in `memoizing?'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/middleware/memoizer.rb:67:in `memoized_call'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/middleware/memoizer.rb:45:in `call'

The stack trace of the bad adapters (the second 2)

.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:28:in `backtrace'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:28:in `initialize'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:220:in `new'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-redis-1.2.2/lib/flipper/adapters/redis.rb:220:in `block (2 levels) in <top (required)>'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/adapter_builder.rb:41:in `to_adapter'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/configuration.rb:29:in `adapter'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/engine.rb:54:in `block (3 levels) in <class:Engine>'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/configuration.rb:65:in `default'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper.rb:46:in `instance'
.rbenv/versions/3.1.4/lib/ruby/3.1.0/forwardable.rb:232:in `memoizing?'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/middleware/memoizer.rb:67:in `memoized_call'
.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/flipper-1.2.2/lib/flipper/middleware/memoizer.rb:45:in `call'

The branching happens with how the adapter builder constructs the redis adapter.

Of course, I can get around the problem if I set the env var FLIPPER_REDIS_URL
However, the documentation doesn't specify that the URL has to come from an env variable.
https://www.flippercloud.io/docs/adapters/redis

It's somewhat inconvenient to have to set the env variable. I have been trying to figure out what changed. I didn't need to set the env var in version 1.1.2.

@jnunemaker
Copy link
Collaborator

@micahtessler I'm not sure how to reproduce this. It sounds like Flipper is getting used during the boot process prior to your custom config possibly? @bkeepers does it sound like that to you or do you have any different ideas?

One option to figure out where this is happening is to bundle open flipper and add something like caller inside the flipper configure block there to see the backtrace of where it's getting invoked from. Once you have that, it should be easier to determine why this is happening.

Can you give that a try and let me know if it helps?

@bkeepers
Copy link
Collaborator

@micahtessler I'm not sure how to reproduce this. It sounds like Flipper is getting used during the boot process prior to your custom config possibly? @bkeepers does it sound like that to you or do you have any different ideas?

I agree, that's what it sounds like.

I edited my local copies of the gems to dump the stack to trace the problem (so some line numbers don't 100% line up).

If youc an paste the whole stack trace, we should be able to tell if it's happening during app boot and where.

@micahtessler
Copy link
Author

micahtessler commented Mar 11, 2024

Not sure what you reference as the boot process. The first initialization happens correctly as you can see above, it calls into my initializer config.
The second and third intializations happen incorrectly and occur afterwards.

so it there was a boot problem, I would expect the opposite, the first initialization would not get the config as it hadn't been set.
The 2nd and third would pick up the correct config as it's set in a rails initilaizer.

@micahtessler
Copy link
Author

What from the stack trace do you need to see specifically?

@jnunemaker
Copy link
Collaborator

What from the stack trace do you need to see specifically?

From inside of the default redis configure block. If you bundle open flipper-redis you can add the require and pp caller in the screenshot. Restart your process and copy the backtrace that gets printed.

backtrace

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

No branches or pull requests

3 participants