osimons wrote:
> I don't have an 'exists' property/method for my FullBlog model for
> blog posts (as one example). For Bitten this is different as a
> resource in the 'build' realm can be either a configuration or a
> specific build number - meaning you can also get completely different
> type of model objects back depending on ID. Nothing can or should be
> assumed about what it represents.

Ok, that's the current state of things in FullBlog and Bitten, but in
both cases, a .exists attribute would make sense, wouldn't it? It
answers a very simple, very general question: does this resource exist?

> The major selling point for 'resources' as a concept was that we
> needed lots of them when dealing with the new security system for
> 0.11, and generally needed a cheap way to create and mutate something
> to identify a Trac resource without instantiating them.

Passing the environment when creating the resource (or the resource
manager) would indeed slow down instantiation, but adding a
get_model(env) method wouldn't have an impact on performance.

> Regardless of
> design discussed and chosen, the idea was that resource and model
> should be very loosely coupled - no actual coupling in fact as nothing
> can be inferred about the underlying model implementation.

I agree that very *little* can be inferred, but .exists still makes
sense to me.

> The 'convenience' we have generally used so far has in fact been the
> other way around as we have attached a Resource object to the Model in
> order to have it at hand. That then causes intermingled and possibly
> circular references.

That's the reason why I suggested to hold back on caching.

> Let 10 able coders stare at the Trac code
> and see if any of them come up with formatter.context.resource.model
> as the obvious starting point to access properties they need...

You mean you like the following better?

  if formatter.context.resource.realm == "wiki":
      model = WikiPage(self.env, formatter.context.resource.id,
                       version=formatter.context.resource.version)

Still, why would you need the model object in a macro?

> Complex
> objects that reference other known and unknown objects in ways that
> are hard to detect, literally caused me months of sleepless nights
> while trying to figure out the rare circumstance why my site went down
> at irratic intervals:
> http://trac-hacks.org/changeset/4366

I agree that there are issues with caching, but model objects really
shouldn't keep open database connections as attributes, so this wouldn't
be an issue here. The Formatter object is a bit special for that (and
why does it keep a .db attribute anyway?).

> As one example against the #8834 ticket (generic resource
> change listening/notification), my FullBlog needs to notify when
> comments are added. Comments are not resources, and they do not create
> a new version of the blog post itself which is separately editable for
> new versions.

Maybe comments *should* be child resources of blog posts, then? Isn't
that the typical use case for child resources?

> Shoe-horning all features into common model-,
> manipulator- and listener infrastructure is contrary to the general
> "feel" of the code base that has made Trac successful and enabled the
> great variety of plugins that we actually have.

I don't think the *heterogeneity* of the model objects in Trac was
responsible for its success with plugins, quite the contrary. Having to
browse the code every time to find out if a model object has a .exists
attribute or raises a ResourceNotFound exception if the resource doesn't
exist is a pain in the backside. A bit more homogeneity would certainly
be welcome (independently of GenericTrac, just in the interfaces exposed
by the model objects).

> I know, at one stage I actually championed accessing model through
> resource, but that was in the name of "security" and not
> "convenience".

While security is certainly more important than convenience, I would not
discard the latter as insignificant. The right convenience placed at the
right location makes code easier to understand and work with, and will
require you to keep fewer concepts in your head while coding.

> now I have a strong preference for simple and explicit.
> Accessing or inferring anything about models through resources is -1
> from me.

I guess this is a matter of perspective, but in this case, I find simple
and explicit to be quite opposite:

  model = WikiPage(self.env, resource.id, version=resource.version)

vs.

  model = resource.get_model(self.env)

Anyway, I don't have all your experience to tap into, so I'd have to see
the code and contrast before / after to judge. And with my current
knowledge, I'd say it's worth a shot.

-- Remy

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to