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
Rack::Builder#to_app
is not designed to be called for every request.
#1083
Comments
Thanks for the report, this is an area of the library I haven't looked much into. Would memoizing the to_app call be sufficient? |
I think you'd want to do it at build time because memoization is not thread safe. |
It's also not necessary to redefine If OmniAuth::Builder is intended to be used as shown in the README, maybe overridding module OmniAuth
class Builder < ::Rack::Builder
def self.new(default_app = nil, &block)
builder = super
block ? builder.to_app : builder
end
end
end |
module OmniAuth
module Builder
def self.new(default_app = nil, &block)
::Rack::Builder.new(default_app, &block).to_app
end
end
end maybe consider this??? |
Except that omniauth/lib/omniauth/builder.rb Line 29 in 7d90ba2
What about this: module OmniAuth
class Builder < Rack::Builder
def initialize default_app = nil, &block
super
@app = to_app if default_app
end
def call env
(@app || to_app).call(env)
end
# The rest same as current OmniAuth::Builder class,
# not duplicated here....
end
end It ought to cover people who are currently using it in both ways, as middleware as suggested in the docs or as |
I don't think side effects in I like your original proposal: #1083 (comment) I'd even suggest just doing it like this: module OmniAuth
module Builder
def self.build(default_app = nil, &block)
new(default_app, &block).to_app
end
# All the existing code.
end
end Then use |
I'm not opposed to a major bump if need be, so the change can be as breaking as needed |
The problem is that omniauth has been telling people to use use OmniAuth::Builder do
provider :developer
end Any Rack-like What about... module OmniAuth
module Builder
def self.new(app, *args, &block)
builder = Rack::Builder.new(app).extend(self)
builder.instance_eval(&block) if block_given?
builder.to_app
end
def provider(klass, *args, **opts, &block)
# ...
end
def options(options = false)
# ...
end
# ...etc
end
end This would work for applications using It would break for people who have been instantiating Builder and using the instance directly, though. |
One more option -- rename the current Builder class to something else and define a new Builder to use it internally. module OmniAuth
class AuthBuilder < Rack::Builder
# ...same as current OmniAuth::Builder, except no #call
undef_method :call
end
class Builder
def initialize app, &block
@app = AuthBuilder.app(app, &block)
end
def call env
@app.call(env)
end
end
end |
If you had a preference on how you wanted this resolved (or the priorities to take into consideration, e.g., what level of backward-compatibility, etc), I'd be willing to take a crack at it and submit a PR. |
I think the biggest downstream consumer is devise, so we'd wanna look if/how devise uses the builder and try and at least keep backwards compatibility for that |
If you want an easy way to test external dependencies, you might like https://github.com/ioquatix/bake-test-external |
Previously, OmniAuth::Builder was a subclass of Rack::Builder. Rack::Builder#call calls #to_app, rebuilding the Rack application on each request, and, as it says in the Rack::Builder comments, this may have a negative impact on performance. This commit renames the original OmniAuth::Builder to OmniAuth::AuthBuilder and replaces it with a wrapper to be used as middleware (as is suggested in the documentation). Using OmniAuth::Builder will now only build the application once. Resolves omniauth#1083.
I searched the devise code. They don't use Builder. The only reference to "builder" is a form builder. I also ran their test suite against the code in the PR just in case, and everything passes. |
Previously, OmniAuth::Builder was a subclass of Rack::Builder. Rack::Builder#call calls #to_app, rebuilding the Rack application on each request, and, as it says in the Rack::Builder comments, this may have a negative impact on performance. This commit changes OmniAuth::Builder from a class to a module and defines a ::new method that extends a Rack::Builder instance with that module, instance_evals any block, and returns the value of #to_app, the built application. Using OmniAuth::Builder will now only build the application once. For users who have been subclassing OmniAuth::Builder, a fix would be subclassing Rack::Builder directly and including OmniAuth::Builder: class MyBuilder < Rack::Builder include OmniAuth::Builder # ... end Resolves omniauth#1083.
Previously, OmniAuth::Builder was a subclass of Rack::Builder. Rack::Builder#call calls #to_app, rebuilding the Rack application on each request, and, as it says in the Rack::Builder comments, this may have a negative impact on performance. This commit changes OmniAuth::Builder from a class to a module and defines a ::new method that extends a Rack::Builder instance with that module, instance_evals any block, and returns the value of #to_app, the built application. Using OmniAuth::Builder will now only build the application once. For users who have been subclassing OmniAuth::Builder, a fix would be subclassing Rack::Builder directly and including OmniAuth::Builder: class MyBuilder < Rack::Builder include OmniAuth::Builder # ... end Resolves omniauth#1083.
I opened another PR, with the Builder-as-a-module idea. I don't really have a preference between them, but the module version means there won't be an extra do-nothing piece of middleware in the stack since it just returns the built app. |
Thanks @speckins I will take a look as soon as I have some time, I've been very busy |
I tripped on this earlier today. How can I help get #1094 merged? |
I've just not had the time to manage a large refactor at the moment, I'd love to be able to take care of a few different long standing issues w/ omniauth in the next major release, I just haven't had the time to work on OmniAuth outside of critical maintenance. Namely I'd like to resolve this issue, completely remove the hashie dependency, not dup the entire strategy w/ every request, and shortcircuit out of omniauth early when the request is not on a path that omniauth cares about. |
Makes sense! What do you think of doing those changes incrementally? I can help. |
omniauth/lib/omniauth/builder.rb
Line 44 in 9cd7aad
It can have less than ideal performance implications.
The text was updated successfully, but these errors were encountered: