[PEAK] FYI: bug in binding.Component and config.ConfigMap

Phillip J. Eby pje at telecommunity.com
Mon Aug 30 00:33:26 EDT 2004


I just discovered a problem with binding.Component and config.ConfigMap 
with respect to their "lazy immutability".  If you use e.g. config.lookup() 
or other mechanism to search for a configuration value, and an individual 
Component has no value specified for that key, this does *not* preclude you 
from later defining that key.

This is a pretty serious error, from the point of view of PEAK's design 
goals, but if you're not aware of this, you may actually have written code 
that relies on this faulty behavior.

An example:

 >>> from peak.api import *
 >>> root = config.makeRoot()
 >>> c = binding.Component(root)
 >>> t1 = config.lookup(c, storage.ITransactionService)
 >>> c.registerProvider(storage.ITransactionService, 
config.Value(storage.TransactionService(c)))
 >>> t2 = config.lookup(c, storage.ITransactionService)
 >>> t1 is t2
False

As you can see, we created a *new* transaction service, and registered it 
with a component that we previously tried to look up a transaction service 
for.  What *should* have happened is that the 'registerProvider()' 
operation should have raised an 'AlreadyRead' exception, indicating that 
some code has already relied on finding 't1'.  It should not be possible to 
then change to using 't2' instead, since this leads to an inconsistent 
configuration.

This problem only occurs when *no* providers of any kind have been 
registered with the component instance.  At some point I put in some code 
to avoid "unnecessarily" creating a configuration map for individual 
components during lookups.  This "saves" creating a configuration map for 
every component, at the cost of a possibly inconsistent configuration view.

Unfortunately, the fix is high-impact: changing it to the correct behavior 
may significantly increase memory consumption for binding.Component 
subclasses.  It will also slow down some configuration lookups.  And 
finally, it will break code that relies on the current behavior.

Therefore, I just wanted to give everybody a heads-up that I intend to fix 
this behavior, because it has the potential to create extremely 
hard-to-find configuration bugs, where some components see a different 
configuration than others, depending on *when* they did their lookups.




More information about the PEAK mailing list