[Chandler-dev] Trellis API rollout plan

Grant Baillie grant at osafoundation.org
Thu Apr 10 09:16:57 PDT 2008


Hi, Phillip

That plan looks highly sensible and good. I'm available for feedback/ 
help (especially with the rearchitecture branch changes) if need be.

--Grant

On 8 Apr, 2008, at 19:47, Phillip J. Eby wrote:
> So, at this point, I have a mostly-baked implementation of the new  
> Trellis API, minus laziness and connect/disconnect support.  It's  
> working side by side with the old API, but I haven't checked it in  
> yet.
>
> Here's what I'm planning to do, more or less in order:
>
> * add laziness and verify that 'compute' rules do not write anything
> * add deprecation warnings for the old API
> * check in the changed code
> * port the Chandler "rearchitecture" branch code to use the new API
> * write a porting guide for others to use
> * update the Trellis tutorial to reflect the changes
> * issue an interim release (0.7a1?) and encourage everyone to move  
> to the new API (since code using the old API will be spewing warnings)
> * add connect/disconnect support
> * drop support for the old API
> * issue a new release (0.7a2?) with connector support and without  
> the old API
> * Start experimenting with using the new connector stuff for  
> functional GUI integration, and resume experimenting with SQLAlchemy  
> integration.
>
> Basically, this means that fairly soon you will start getting  
> deprecation warnings if you're working from an SVN version of  
> Trellis, and until I get a porting guide together, you're going to  
> have to look to the changes I've made in SVN as a guide.  Here's a  
> quick-and-dirty reference for your convenience:
>
> variable(initially=NO_VALUE, resetting_to=NO_VALUE):
>    * value(X)    -> variable(initially=X)
>    * receiver(X) -> variable(resetting_to=X)
>
> variable.attributes(**):
>    * values(**) -> variable.attributes(**)
>
> variable.attributes.resetting_to(**):
>    * receivers(**) -> variable.attributes.resetting_to(**)
>
> perform(rule=None, optional=False):
>    * observer(X) -> perform(X)
>    * @observer X -> @perform X
>    * @optional @observer X -> @perform(optional=True) X
>
> Those are the easy translations, because they're 1:1.  For existing  
> uses of 'rule', 'discrete', and 'optional', it's a bit tougher,  
> because they will become either 'compute' or 'maintain', depending  
> on the context.
>
> If you have a rule with no side-effects, you should use 'compute',  
> and if your rule has side-effects, you should use 'maintain':
>
> compute(rule=None, initially=NO_VALUE, resetting_to=NO_VALUE,  
> writable=False):
> maintain(rule=None, initially=NO_VALUE, resetting_to=NO_VALUE,  
> optional=False):
>
> 'compute' rules are always optional (i.e., not activated until  
> needed), and 'maintain' rules are always writable (i.e., the  
> attribute can be set).  Both APIs can use 'initially' or  
> 'resetting_to' in order to set an initial value or make the rule  
> discrete (i.e., automatically resetting after a change).
>
> If you don't pass in a rule, the API acts as a decorator, and can be  
> used as in these examples:
>
>    @trellis.compute
>    def some_rule(self):
>        ...
>
>    @trellis.maintain(initially=42):
>    def another_rule(self):
>        ...
>
>    some_attr = trellis.compute(lambda self: {})
>
> etc.
>
> 'compute' rules will be lazily recomputed, in that they will not be  
> re-run unless some other rule is actively subscribed to its output.   
> (Attempting to read the rule's value will trigger recalculation if  
> the value is out of date, however.)  This, combined with the lazy  
> initialization of compute rules, means that compute rules will be of  
> generally lower overhead than 'maintain' rules, which must always be  
> re-run when a dependency changes (because the rule might have side- 
> effects).
>
> To replace the 'rules()' API, there will be two new variations:
>
> compute.attributes(**)
> maintain.attributes(**)
>
> Note also that in the past, you could combine rules() and values()  
> definitions for the same attribute, but that will not be possible  
> with the new API.  A given attribute now has to be defined in  
> exactly one place.  If you were previously defining both a rule and  
> value for an attribute, you will need to either use  
> maintain(initially=val), or compute(initially=val, writable=True) to  
> define the rule.
>
> Inheritance of attribute metadata has also changed; instead of  
> querying metadata registries, you can simply refer to  
> 'SomeBaseClass.some_attr.rule' to retrieve the rule for 'some_attr'  
> in SomeBaseClass'.
>
> At this point, this is a very early draft, and it's possible that  
> during the remaining porting of the tests and the Chandler rearch  
> branch I'll want to tweak these APIs in some way.  This is just a  
> snapshot based on what I have in my local checkout right now.
>
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> Open Source Applications Foundation "chandler-dev" mailing list
> http://lists.osafoundation.org/mailman/listinfo/chandler-dev



More information about the chandler-dev mailing list