[openstack-dev] [oslo] usage patterns for oslo.config

Doug Hellmann 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
>>>> 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.


> Oh look, we have a FAQ on this:
> https://wiki.openstack.org/wiki/Oslo#Why_does_oslo.config_have_a_CONF_object.3F_Global_object_SUCK.21
> Mark.
> _______________________________________________
> OpenStack-dev mailing list
> OpenStack-dev at lists.openstack.org
> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

More information about the OpenStack-dev mailing list