[openstack-dev] [oslo] usage patterns for oslo.config
doug at doughellmann.com
Tue Aug 26 14:00:52 UTC 2014
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
>>> 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
> * 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.
> Oh look, we have a FAQ on this:
> OpenStack-dev mailing list
> OpenStack-dev at lists.openstack.org
More information about the OpenStack-dev