Re: Schema-by-interface options
"Kapil Thangavelu" <k_vertigo-5YxZ1of64+Pk/[email protected]> Thu, 21 Sep 2006 01:58:28 -0700
| Newsgroups | gmane.comp.web.zope.plone.archetypes.devel |
|---|---|
| Organization | ObjectRealms, LLC |
| Message-ID | <[email protected]> |
On Thu, 21 Sep 2006 00:49:46 -0700, Martin Aspeli <[email protected]> wrote: > Kapil Thangavelu wrote: >> On Wed, 20 Sep 2006 15:46:40 -0700, Martin Aspeli <[email protected]> >> wrote: > >>> - Does this have any mechanism for adding things to schemas more >>> globally, i.e. install a 'tag' field on all ITaggable or an >>> 'annoyingCorporateContentIdNumber' on all AT objects? >> the primary purpose is providing per instance customization, but the >> global, flavor on by default is possible, via few means, one is a >> custom flavorprovider adapter that always returns the global flavors >> (with adapter specification for either ITaggable or IBaseContent), but >> doing so requires forgoing marker interface application to content >> which are applied & removed during flavor lifecycle/mutation >> management, and which are central feature point of the system, ie. >> being able to apply both AT schemas, and z3 components at runtime on an >> instance basis. > > Okay, I think I may not understand this completely, probably because I'm > looking at it from a slightly different perspective. Could you explain > the original use case(s) by means of an example, just to make sure we're > on the same page? okay let's say i have an article content type, i have several different flavors so to speak of article, feature, book review, movie review, biography, etc. ie. a common base type w/ different applicable schemas and views based on usage. another example... i have a places content type, which has movie theaters, restaurants, museums, parks, bars, etc (ad nauseum). this is a better example of the notion of wanting multiple flavors on a content type, ie. a place is both a bar and a restaurant, both flavors contribute additional specific schema. last example, plone.rules ;-) firing to add a press release flavor to a news items put in press folder. > >>> - Do you support extended schemas per-class or per-instance? >> per instance, adding an additional per class semantic seems strange in >> my opinion, in that AT already provides this. i could add an additional >> semantic for global application of flavors, although i'm still unclear >> on the use cases, though its easy enough for integrators to add global >> semantics with per site customization via an objectcreated event >> adapter for flavor application in zope 2.10. > > Storing schemas persistently per-instance has shown to be troubling in > the past (migration issues, for one). ContentFlavors does not store schemas persistently per instance or persistently at all, all schemas are preeminent on disk. changing the on disk schema definition, and restarting zope, instantly refreshes content schema as it would with a normal class defined schema. there are two persistent changes to the instance when applying flavors, an annotation of flavor names, and optionally if a flavor marker interface is specified a directly provides declaration on the content. > The two use cases I find most difficult at the moment (that my/whit's > branches are trying to solve) are: > > - Install product MyNews and the News type gets an extra two fields, a > new view template and a new action. > > In b-org, this is done by registering an appropriate (possibly local) > adapter for the schema, and possibly changing the FTI upon install. > in content flavors, this would be done by applying a custom interface to news type, registering a flavor with an at schema for the two fields, registering views (with browser menus) against the custom interface (cmonfive does action conversion) registering a (possibly local) flavor provider that provides the new flavor schema and marker to the news type interface. since contentflavors doesn't touch the atcore, it requires the news type to mixin flavoraware, although once their is any sort of delegation it falls out just as well. configuring the interface application in zcml, means that the lifecycle management for markers isn't nesc. > - Install product MyTagging, which applies ITaggable to a bunch of > content types. ITaggable implies that these content types also have a > 'tag' field in their schema. > > In b-org, this is done by registering a new ISchemaExtender adapter. On > my branch, I've tried to generalise this a bit - you adapt self to > ISchemaComposer to get back a single schema, and this in turn look up > all adapters from (context, composer) to ISchemaProvider, which can > provide fragments of a schema. The default provider just looks as > klass.schema (and there is caching going on). Providers are ordered. this scenario is pretty much the same with contentflavors, with the registration of the flavor and the adapter to flavor provider. in fact it comes out exactly the same as the previous scenario. > >>> - Is it possible for a particular flavor to be installed in one Plone >>> site but not in another (in the same Zope instance) >> flavors are mostly just sugar around adapters, a local component >> registry, and changing all the adaptation lookups to provide context ( >> assuming some appropriate icomponentlookup adapters for AT content) >> would allow for this. > > You don't need to pass 'context' to adapter/utility lookups to have it > prefer local adapters over global ones (at least not in Zope 2.10) - > Zope 3's threadlocal acquistion knows which component registry to use, > and falls back on the global by default. In *tests* you need to call > setHooks(), setSite(ploneSite), but that's about it. interesting. i need to checkout the site stuff in zope.app.component.. the stuff in zope.component assumes an adapter from context to IComponentLookup > >> once you have per instance semantics, caches become tricky, due to the >> need for at initialization of accessors/mutators per instance, and you >> have the notion of ordered schemas which allow for field overriding, or >> class directly implementing custom accessors/mutators for applied >> schemas. that said there are some potential optimizations here for a >> smart cache, with a lookup of (class, flavor name tuple) -> (schema, >> accessor/mutator dict) for limiting memory consumption and composition. > > The thing that shot down VariableSchemaSupport and friends was always > that it'd do the ClassGen dance on every or almost every access to > Schema(), which is very slow. With Z3 events, I see no problem in having > a cache that's explicitly invalidated in an event handler, since the > code that mutates the schema can fire the event. The hard part is > picking the right cache key. aye, variableschemasupport had some borked and expensive hash method which always failed afaicr, volatile caches are compariatively fast and well known. if the object is in memory its _v_schema is only going to be composed once till the object is either ghosted or mutated, incidentally, contentflavors already does instance cache invalidation via event, though moving to the cache keys i proposed previously, you never need to invalidate a composed schema, just signal accessor/mutator gen on instance. > >>> - Why is the FlavorUtility not registered as a utility? >> because it was a decoy, its been removed, this code has been under >> active development all day ;-) its stable after as of this email, in >> that feature development is complete. > > Oh, great. I'll try to check it out later. If I take a more active > interest in it, could we shift it to the AT svn repo or the Collective? > I'll branch of course! > >> the at minimal mixin the system needs is in aware.py.. basically just >> delegates for Schema() and getIcon(), the schema delegation could be >> any such implementation that defers to the CA for an adapter, and >> contentflavors could integrate for management, though i have questions >> regarding getting the z3 management ui view on applicable adapatable >> content, without a declared interface on the content. > > You can apply interfaces from outside the package, though, with > alsoProvides() or <five:implements>. yeah, that works fine. > >>> The main problem is that, as you've discovered, you need to >>> re-generate methods ClassGen style when things change (and at least >>> once) at run-time, since ClassGen is only run once and is only aware of >>> the 'schema' class-attribute. This has performance implications, if >>> nothing else. I'd rather that functionality was in AT. >>> >> such functionality is already duplicated elsewhere (atseng comes to >> mind) to support different semantics, one implementation to rule them >> all doesn' really seem all that z3ish ;-) > > That's true. But if AT says, "I support the application of schemas by an > adapter lookup", then that *does not work* without calling a > ClassGen'ish thing at least once (after the lookup of the schema has > been made the first time). This is because AT's basic ClassGen works at > class loading time, and cannot do the adapter lookup (no context), and > it relies on the .schema class-variable, which cannot be made dynamic > like an instance-variable could wither @property. So, I think it'd dumb > to support some way of delegating schemas to an adapter if you know that > anyone who actually uses that functionality *must* do a dance with > generating methods, opening that up to re-invention and bugs and > possibly conflicts. but those schema adapters are all going to have different semantics potentially different semantics about lifecycle (ie. the always on case, really only needs once in a process, instance mutation on mutation ).. which is exactly why people have reimplemented classgen semantics that work for their use cases, coming up with a base set of common primitives for doing the drudgery is a step forward, but the application is always going to be adapter driven. you can separate out to two stage adapters which is what contentflavors does (although it takes a step further in that you don't need an adapter just point a zcml flavor to a schema), such that folks just wanting to use the framework to add schema don't have to deal with class gen semantics, but the top level integration adapter ( schemasetprovider for lack of a better term) has to know when it needs to apply accessor/mutator generation (or defer via event to an adapter who does). ie when you talk about changing things at runtime which need initialization, you have to know there was a change, and knowing that depends on what your doing. ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV