[TransWarp] Finding an object that provides the interface (was: Infinite recursion computing a binded attribute)
Oleg Broytmann
phd at work.phd.pp.ru
Wed May 21 12:02:55 EDT 2003
On Tue, May 20, 2003 at 12:05:50PM -0400, Phillip J. Eby wrote:
> At 05:49 PM 5/20/03 +0400, Oleg Broytmann wrote:
> >Hello! I've got a problem. Infinite recursion. I think I am doing something
> >wrong, but what?
> >
> > Let me briefly describe my hierarchy of classes:
> >
> >class Component(binding.Component):
> > appname = binding.bindTo("appname")
> > appver = binding.bindTo("appver")
> > log = binding.bindTo("log")
>
> Maybe I'm confused, but based on your config file, shouldn't this be
>
> log = binding.bindToProperty("MedapE.log")
> ???
No, this binds to application's log. In previous version of peak this
code was
log = binding.bindTo("/log")
> > Components are loaded from config file:
> >
> >[Provide Utilities]
> >ank.MedapE.interfaces.IUiFrontend =
> >config.provideInstance('ank.MedapE.UiFrontEnd.BaseHTTPD.BaseHTTPD')
> >ank.MedapE.interfaces.IUiServer =
> >config.provideInstance('ank.MedapE.UiServer.HtmlServer.HtmlServer')
> >
>
> >components = "ui", "httpd"
> >component.ui = "ank.MedapE.UiServer.HtmlServer.HtmlServer"
> >component.httpd = "ank.MedapE.UiFrontend.BaseHTTPD.BaseHTTPD"
>
> I don't understand what this part above does.
There is a component loader, which inports and initialize classes
according to the app.components list and app.component.* classes.
> I've now found and fixed the recursion in PEAK, so you
> will just get 'NameNotFound' errors instead.
Yes, I got it. And I found the reason. There are two instances of (some
of) my components. One instance was created by the component loader
mentioned above. These instances were provided with correct parentComponent
and hence they can acquire .log and other attributes. Other, "wrong"
instances were created by binfingTo. For example:
class ScenarioServer(Runnable.Runnable):
protocols.advise(instancesProvide=[interfaces.IScenarioServer])
class HtmlServer(ThreadRunnable.ThreadRunnable):
protocols.advise(instancesProvide=[interfaces.IUiServer])
# link to ScenarioServer
s_server = binding.Once(
lambda s, d, a: config.findUtility(s, interfaces.IScenarioServer),
doc="Main application server (ScenarioServer)")
In the HtmlServer instances first reference to self.s_server created new
ScenarioServer instance (due to [Provide Utilities]) with wrong
parentComponent - peak.config.config_components.ConfigurationRoot instead
of my application object.
Why findUtility does not find already created instance of
ScenarioServer?
Initially (as I have said some emails ago) the classes was declared as
class ScenarioServer(Runnable.Runnable):
__implements__ = interfaces.IScenarioServer
and application loader registered their interfaces for findUtility. It
seems classes declared in [Provide Utilities] are instantiated instead of
being looked up someplace.
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ phd at phd.pp.ru
Programmers don't die, they just GOSUB without RETURN.
More information about the PEAK
mailing list