[Freeipa-devel] [PATCH] 1 Do lazy initializiation ipalib
Martin Kosek
mkosek at redhat.com
Thu Nov 3 08:30:27 UTC 2011
On Wed, 2011-11-02 at 18:38 +0200, Alexander Bokovoy wrote:
> (actual patch attached!)
>
> On Wed, 02 Nov 2011, Alexander Bokovoy wrote:
> > On Wed, 02 Nov 2011, Jan Cholasta wrote:
> > > >Callable instances are a consequence of the above --
> > > >Command.__call__() does use properties that are changed due to
> > > >finalize() being run. In fact, there are so many places in FreeIPA
> > > >where we simply expect that foo.args/params/output_params/output is
> > > >both iterable and callable instance that it is not even funny.
> > > >
> > > >Now, the process established by the proposed patch is actually
> > > >dependent only on the fact that bound instance has finalize() method.
> > > >This is quite generic and can be used for all other types of objects.
> > > >
> > >
> > > The real problem is in the API class so it should be fixed there,
> > > not worked around in Plugin subclasses.
> > Please explain why you do think real problem is in API class.
> > Finalize() is needed purely to being able to split plugins' property
> > initialization into stages before loading plugins and after due to the
> > fact that each and every plugin could contribute commands and
> > additions to the same objects. While these stages are separate,
> > plugins can access properties and commands they want and it is duty of
> > a plugin to get its property working right. We have finalize() method
> > exactly for this purpose.
> >
> > API class' attempt to call finalize() on each plugin's instance at
> > once is a poor replacement to detecting access to
> > not-yet-initialized properties. We can implement that access like you
> > have proposed with __getattribute__ but it has additional cost for all
> > other properties that don't need post-initialization (finalization)
> > and, what's more important, they incur these costs irrespective
> > whether initialization has happened or not. That's bad and my patch
> > shows it is actually noticeable as the performance difference, for
> > example, of 'ipa dnsrecord-find example.com' between the two patches
> > is about 2x in favor of my patch (1.624s vs 0.912s).
> >
> > Regarding other objects, here is the list of places where we define
> > specific finalizers:
> > $ git grep 'def finalize'
> > ipalib/cli.py: def finalize(self):
> > ipalib/frontend.py: def finalize(self):
> > ipalib/plugable.py: def finalize(self):
> > ipalib/plugable.py: def finalize(self):
> > ipaserver/rpcserver.py: def finalize(self):
> > ipaserver/rpcserver.py: def finalize(self):
> > ipaserver/rpcserver.py: def finalize(self):
> > tests/test_ipalib/test_cli.py: def finalize(self):
> > tests/test_ipalib/test_config.py: def finalize_core(self, ctx, **defaults):
> > tests/util.py: def finalize(self, *plugins, **kw):
> >
> > As you can see, there NO plugins that define their own finalizers,
> > thus, all of them rely on API.finalize(), help.finalize(), and
> > Plugin.finalize()/Command.finalize(). ipaserver/rpcserver.py
> > finalizers are fine as well, I have checked them.
> >
> > Updated patch is attached. It addresses all comments from Martin.
> >
> > [root at vm-114 freeipa-2-1-speedup]# time ipa dnsrecord-find ipa.local >/dev/null
> >
> > real 0m0.883s
> > user 0m0.504s
> > sys 0m0.136s
> > [root at vm-114 freeipa-2-1-speedup]# time ipa user-find >/dev/null
> >
> > real 0m0.887s
> > user 0m0.486s
> > sys 0m0.141s
> > [root at vm-114 freeipa-2-1-speedup]# time ipa group-find >/dev/null
> >
> > real 0m0.933s
> > user 0m0.446s
> > sys 0m0.169s
> > [root at vm-114 freeipa-2-1-speedup]# time ipa help >/dev/null
> >
> > real 0m0.624s
> > user 0m0.479s
> > sys 0m0.133s
> > [root at vm-114 freeipa-2-1-speedup]# time ipa group >/dev/null
> >
> > real 0m0.612s
> > user 0m0.475s
> > sys 0m0.126s
> > [root at vm-114 freeipa-2-1-speedup]# time ipa user >/dev/null
> >
> > real 0m0.617s
> > user 0m0.472s
> > sys 0m0.131s
> >
> > --
> > / Alexander Bokovoy
>
Good, this indeed addresses all my previous concerns but one :-)
$ ./makeapi
Writing API to API.txt
Traceback (most recent call last):
File "./makeapi", line 392, in <module>
sys.exit(main())
File "./makeapi", line 376, in main
rval |= make_api()
File "./makeapi", line 167, in make_api
fd.write('args: %d,%d,%d\n' % (len(cmd.args), len(cmd.options), len(cmd.output)))
But if you change "len" functions to "__len__" it works fine.
Martin
More information about the Freeipa-devel
mailing list