[openstack-dev] [oslo] usage patterns for oslo.config
markmc at redhat.com
Wed Aug 27 06:20:51 UTC 2014
On Tue, 2014-08-26 at 10:00 -0400, Doug Hellmann wrote:
> On Aug 26, 2014, at 6:30 AM, Mark McLoughlin <markmc at redhat.com> wrote:
> > On Mon, 2014-08-11 at 15:06 -0400, Doug Hellmann wrote:
> >> On Aug 8, 2014, at 7:22 PM, Devananda van der Veen <devananda.vdv at gmail.com> wrote:
> >>> On Fri, Aug 8, 2014 at 12:41 PM, Doug Hellmann <doug at doughellmann.com> wrote:
> >>>> That’s right. The preferred approach is to put the register_opt() in
> >>>> *runtime* code somewhere before the option will be used. That might be in
> >>>> the constructor for a class that uses an option, for example, as described
> >>>> in
> >>>> http://docs.openstack.org/developer/oslo.config/cfg.html#registering-options
> >>>> Doug
> >>> Interesting.
> >>> I've been following the prevailing example in Nova, which is to
> >>> register opts at the top of a module, immediately after defining them.
> >>> Is there a situation in which one approach is better than the other?
> >> The approach used in Nova is the “old” way of doing it. It works, but
> >> assumes that all of the application code is modifying a global
> >> configuration object. The runtime approach allows you to pass a
> >> configuration object to a library, which makes it easier to mock the
> >> configuration for testing and avoids having the configuration options
> >> bleed into the public API of the library. We’ve started using the
> >> runtime approach in new Oslo libraries that have configuration
> >> options, but changing the implementation in existing application code
> >> isn’t strictly necessary.
> > I've been meaning to dig up some of the old threads and reviews to
> > document how we got here.
> > But briefly:
> > * this global CONF variable originates from the gflags FLAGS variable
> > in Nova before oslo.config
> > * I was initially determined to get rid of any global variable use
> > and did a lot of work to allow glance use oslo.config without a
> > global variable
> > * one example detail of this work - when you use paste.deploy to
> > load an app, you have no ability to pass a config object
> > through paste.deploy to the app. I wrote a little helper that
> > used a thread-local variable to mimic this pass-through.
> > * with glance done, I moved on to making keystone use oslo.config and
> > initially didn't use the global variable. Then I ran into a veto
> > from termie who felt very strongly that a global variable should be
> > used.
> > * in the end, I bought the argument that the use of a global variable
> > was pretty deeply ingrained (especially in Nova) and that we should
> > aim for consistent coding patterns across projects (i.e. Oslo
> > shouldn't be just about shared code, but also shared patterns). The
> > only realistic "standard pattern" we could hope for was the use of
> > the global variable.
> > * with that agreed, we reverted glance back to using a global
> > variable and all projects followed suit
> > * the case of libraries is different IMO - we'd be foolish to design
> > APIs which lock us into using the global object
> > So ... I wouldn't quite agree that this is "the new way" vs "the old
> > way", but I think it would be reasonable to re-open the discussion about
> > using the global object in our applications. Perhaps, at least, we could
> > reduce our dependence on it.
> The aspect I was calling “old” was the “register options at import
> time” pattern, not the use of a global. Whether we use a global or
> not, registering options at runtime in a code path that will be using
> them is better than relying on import ordering to ensure options are
> registered before they are used.
I don't think I've seen code (except for obscure cases) which uses the
CONF global directly (as opposed to being passed CONF as a parameter)
but doesn't register the options at import time.
More information about the OpenStack-dev