[Zope] Private Product Objects (was: object icons)

Martijn Pieters mj@digicool.com
Thu, 24 Feb 2000 05:54:18 -0500


From: Loren Stafford [mailto:lstaffor@dynalogic.com]
> > > Now that I've had breakfast and thought about this a 
> little more, I see
> > > there is broader issue: how to handle the special needs 
> of objects that
> are
> > > private to a product. My product is an event scheduler. 
> (Terry, who
> started
> > > the "object icons" thread, may have a different 
> situation. Jump in and
> tell
> > > us about your product, Terry.) The Scheduler product registers an
> > > catalog-aware Event class so user's can define scheduled 
> events. The
> product
> > > keeps track of all Events in a ZCatalog "Schedule". Now, 
> Schedule is a
> > > persistent object and has a class definition, but the one and only
> instance
> > > is created by the product and load time, if an instance 
> doesn't already
> > > exist. The Schedule has some special usage requirements:
> > >
> > > 1. There should be only one instance. That's why its class is not
> > > registered.
> >
> > Hmm, I guess I don't see the necessity of making it a 
> Singleton here.
> Suppose
> > you need to segregate events into separate priority 
> classes, or guarantee
> that,
> > when executed, the run with the permissions of different 
> users?  Splitting
> up
> > the schedule _might_ not be a terrible thing to do.  Your 
> default case
> could
> > then just require dropping a single instance of the 
> Schedule class at the
> root
> > of your Zope hierarchy, and leaving it there.
> 
> I'm beginning to think that way too. I haven't really dealt 
> with priority or
> permissions  yet (and I probably won't until Phase II), but trying to
> enforce a singleton is more trouble than it's worth.

What are your problems? Doesn't my code work anymore?

The reasons I chose to make ZScheduler a singleton are:

1. Extra threads in Zope affect the performance of Zope. Only one
ZScheduler object needs only one extra thread.
2. Event objects should be able to find the ZScheduler at all times,
just like the Add list can count on the id Control_Panel existing.
3. The ZScheduler object can act as a management interface into the
underlying Events, like show what events are about to be executed, show
reports on the number of Events executed, etc.

Priority could simply be a property on a Event object, something that
can then be sorted on from the catalog. No multiple Schedulers needed
here.

> > >
> > > 2. It probably shouldn't show up on users' navigation 
> bars and folder
> lists.
> > > This probably is not a problem, because Schedule has a 
> unique meta-type.
> But
> > > that's not a watertight solution. A standard method for marking it
> invisible
> > > would be better.
> >
> > If Schedule derives from ZCatalog, as it seems, and the 
> Event class uses
> the
> > well-known schedule ID as its default_catalog_id, then it isn't even
> necessary
> > to "contain" the events within the schedule object -- they 
> will find it
> anywhere
> > above them in the tree by acquisition (think "uncle 
> Schedule" instead of
> "papa
> > Schedule").
> 
> I guess I envisioned a single Schedule, because I imagined 
> only a single
> Dispatcher thread. If there are more Schedules, either the 
> Dispatcher will
> need a catalog to find all of the Schedules, or each Schedule 
> will need it's
> own dispatcher. Let me hold that last thought for awhile...

Again, there is no need to have more than one Scheduler, you solve no
problems with that, you only create more.

You don't need to hide the ZScheduler from view, just like you don't
need to hide the Catalog. It can be used as a organising container for
everything related to Events as well. Stock Catalog objects are
containers for the same reasons.

> >
> > >
> > > 3. If and when it does show up (as on the manage_main 
> menu) it should be
> > > identified with the product (to avoid the "Whaz dis?" 
> confusion). That's
> why
> > > I want it to have an icon that shows it is part Scheduler product.
> >
> > Solved if Schedule is an "ordinary" ZClass.
> Check.
> 

Solved if you cannot manually add new Scheduler objects. KISS, keep it
simple, stupid.

> >
> > >
> > > 4. No one, not even a manager, should be able to delete 
> it accidently.
> You
> > > can make an object undeletable by putting its ID in the 
> list of reserved
> > > names, but I have found, during development of Scheduler, 
> that this hack
> > > causes more problems than it's worth. I might settle for 
> letting be
> deleted
> > > by a manager.
> >
> > Again, solved for "ordinary" ZClass instances -- just set 
> the permissions
> so.
> 
> I sort of agree. One problem with deleting a Schedule is if 
> it has events
> cataloged in it -- currently that breaks the event objects. A
> manage_beforeDelete method could just block a delete in that 
> case. Also the
> Dispatcher task has to be terminated. There must be a way to 
> do that in a
> manage_beforeDelete method.
> 
> Martijn what do you think? You clearly went to a lot of 
> trouble to put the
> Product in control of deleting the Schedule catalog.

What are the problems you are experiencing? Especially for the
development and alpha/beta stages of the ZScheduler product, I put a
hook onto the ZScheduler Product folder to release the protection on the
root ZScheduler object when you delete the Products folder. Yes, it is a
hack, but it worked for me. I planned on removing it when releasing a
stable version.

For the reasons I went through all the trouble (which wasn't all that
much of a trouble, really. Zope provided the framework), I named earlier
in this email.

> > >
> > > 5. When the product is deleted (I mean really deleted, 
> because you don't
> > > want to use it anymore), the Schedule should be deleted 
> too. Failing
> this,
> > > it should at least be deletable (an iffy situation, if you use the
> > > reserved_names hack). On the other hand, if you are just 
> updating the
> > > product code, you probably don't want to delete the 
> Schedule object. It
> may
> > > contain scheduled events. This is complicated by the fact 
> that when you
> load
> > > a product, Zope first deletes the old product. So a 
> manage_beforeDelete
> > > method can't distinguish between a "real" delete and a 
> code update. I've
> > > also discovered that any error in a product's 
> manage_beforeDelete method
> > > makes the product not only undeletable, but (because of 
> the implicit
> delete)
> > > unupdatable (un-update-able)!
> > >
> > >   (Hmmm. There's an idea. You could make any object, including the
> Schedule,
> > > undeletable by giving it a manage_beforeDelete method 
> that raises an
> error.)
> > >

Indeed, don't delete the ZScheduler automatically. Just state in the
documentation that this is unstable, development-grade software, and
document the procedure. A product update then will cause the lock to be
removed, and then reinstated.

If you run into problems with the code, you can use the Monitor to
release the lock manually.

> > > 6. The Schedule need to have a "well known" ID (I think). 
> This is for
> use in
> > > the default_catalog property of the events. I wouldn't 
> want someone to
> > > change the ID of the Schedule arbitrarily. This may be 
> the same problem
> as
> > > accidental deletion.
> >
> > You can override the setId() method to prefent changing the id;
> BasicUserFolder
> > does this::
> >
> >
> >     def _setId(self, id):
> >         if id != self.id:
> >             raise Globals.MessageDialog(
> >                 title='Invalid Id',
> >                 message='Cannot change the id of a UserFolder',
> >                 action ='./manage_main',)
> >
> 
> Thanks. I'll use that.
> 

Doesn't using the proetction I implemented also protect you from
changing the id? It should! You can't change the id of the
standard_html_header/_footer and Control_Panel either, can you?

Anyway, since I sort of dumped the code on you, please feel free to ask
more questions =)

-- 
Martijn Pieters, Software Engineer 
| Digital Creations http://www.digicool.com 
| Creators of Zope      http://www.zope.org 
| mailto:mj@digicool.com       ICQ: 4532236
| PGP:
http://wwwkeys.nl.pgp.net:11371/pks/lookup?op=get&search=0xA8A32149 
-------------------------------------------