Something like this is slated for Zope 2.6. If possible (and that's a big if at the moment, with the work we've got lined up), it is my intention to create a service which does the following:
- Searches for an appropriately-named on-disk directory (var/startup probably). - Iterates over the contents of the directory, finding all .py files and turns them into python modules. - Searches each module for a well-known top-level function (named "onstart" or something similar) and calls the function with a single argument, which will be the Zope "application" (root) object. - The code does whatever arbitrary thing that it needs to do, using the application object as a gateway with which it can manipulate persistently-stored objects in the ZODB if necessary. - Optionally, the code deletes itself (if this is a run-once sort of thing) or places a marker in the database (or on the filesystem) that says it should not run again at startup. - The code finishes. The two things that I think are different about this than what you specified is that in my conception, the startup folder is not a persistent Zope object, and you would need to place files in a directory on disk to hook the startup process. It also solves the problem of needing to have a handle to I think your idea of registering a callback to ensure that startup is complete before performing any actions is very sound. I think a callback can be registered almost anywhere, but a plausible place to create the registration method might be in lib/python/OFS/Application.py. Then the callback should probably be called by lib/python/Zope/__init__.py (somewhere after "OFS.Application.initialize(c)", after which point all Products should be initialized). This is a little brittle, though. A better way to do this would be to create a generic Zope scheduling module. This is where hooking the asyncore mainloop would be very appropriate. Unfortunately, the implementation is a bit more complex because you'd probably need to make sure the scheduler didn't hold up the mainloop, and that means kicking off one or more threads to do the work instead of using the main thread just at startup. However, it would be much more generally useful and forward-thinking to implement it this way, even if it was a stub that didn't actually do anything but startup stuff at first. If I were to do this, I would: - Implement a stub scheduler module that was really dumb and only knew how to do "run once, now" jobs (no run-many jobs, no run-then jobs). Do this so as to not go insane trying to reinvent cron and at at the moment. ;-) - Implement a non-Product "Startup" module that did what I explain above, but registered a callback with the scheduler instead of with the method called by Zope/__init__. - Change medusa's asyncore so that the "poll" (and poll2, and poll3) function kept track of when the scheduler had last been run. - In asyncore, when either the select call times out or the last time the schduler was run was over "X" seconds in the past, call in to the scheduler, telling it to wake up, modifying the "last run" time. - The (dumb) scheduler would wake up and notice that it had a job and would kick off a thread which would call back in to the startup code. Then it would remove the job from its queue and go on with its life, which would be absolutely desolate until the next time Zope started up. This architecture would facilitate innovations (like a *real* scheduling facility ;-) in the future. HTH, - C ----- Original Message ----- From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, April 24, 2002 11:56 PM Subject: [Zope-dev] Running methods on Zope startup. > Is there a Zope product out there which implements a "Startup" like folder > for Zope? That is, I want to be able to have a folder like object called > "Startup" in the root directory, and when Zope is first started I want > Zope to automatically make a call against the "Startup" object which could > then in turn run methods of any user defined objects which have been added > into the "Startup" folder to perform special processing only when Zope is > started. > > Imagine a situation similar to database connections. With database connections > when you create it you can indicate that you want the connection established. > Now when Zope is restarted, those database connections will be automatically > restarted when Zope restarts. Although, I am not sure whether this is when > Zope actually starts or when the next request using that database happens. > > Anyway, I ultimately want to be able to have a Zope product which has a > persistent interprocess messaging connection to another process. Although > when first added into Zope the connection can be initiated, I know of no > way to have Zope restart that connection when it restarts. I can't rely on > the connection only starting when someone tries to access the resource, I > want it to happen straight away upon Zope restart. > > When I thought about it, I figured the most basic thing to do would be to > have a Zope "Startup" folder as described in a known place. I could then > stick in that folder, methods to be triggered at startup which could startup > the interprocess communications link for me. This seemed better than having > a startup mechanism specific to what I was doing as it could be used for > other things as well. > > Can anyone point me to such a Zope product. I have started looking at how > to do it myself and have some of the bits in place. The first issue is that > when the "initialize()" method in the product "__init__.py" file is called > not all Zope startup has occured, so it is too early to trigger things from > that point. Best I could come up with there was to register a callback to > asyncore to be called when asyncore mainloop is actually run, which is after > all Zope startup has been done. > > The next problem is getting an appropriate context to be able to start making > calls into Zope objects. The "initialize()" method gets a product context, > but doesn't have public access to the application context. Is there some way > of accessing the Zope application context and thus root folder where you > don't otherwise have a handle to it? Can Main.bobo_application be used? > > Even if the application context is obtained, is it safe to be making calls > into Zope objects from a callback from asyncore? Is there a better way? > > I am very new to Zope and this is my first adventure into making a Zope > product and thus could be totally off track. If anyone understands what > I am trying to do and can suggest how to do it or point at something that > does what I want, then even better. > > Personally I would be surprised if this hadn't already been done or even > that there is some inbuilt way of doing it now, as it opens up all sorts of > interesting possibilities. > > Appreciated if responses are cc'd to me as well as going to the list as I > am not a member of the list yet and am using list archives. > > Thanks in advance. > > -- > Graham Dumpleton ([EMAIL PROTECTED]) > > > _______________________________________________ > Zope-Dev maillist - [EMAIL PROTECTED] > http://lists.zope.org/mailman/listinfo/zope-dev > ** No cross posts or HTML encoding! ** > (Related lists - > http://lists.zope.org/mailman/listinfo/zope-announce > http://lists.zope.org/mailman/listinfo/zope ) > _______________________________________________ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )