provide basic job managemen

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3018 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-11-30 13:42:54 +00:00
parent ebf4d37817
commit e184ed92a7
8 changed files with 218 additions and 0 deletions

View file

@ -6,4 +6,10 @@ $Id$
0.9
---
- basic job management: a job executor view calls job managers specified
by loops root option ``organize.job.managers``
- allow ``__getitem__`` on Loops and ViewManager, this is a prerequisite for
using virtual hosts over more than one path element (e.g. leading to
views/home) on protected sites; this also allows calling of job processiong
views via wget without login credentials
- add definition of loops package version (see loops/version.py)

View file

@ -68,6 +68,7 @@
<!-- include -->
<include package=".browser" />
<include package=".job" />
<include package=".personal" />
<include package=".process" />
<include package=".stateful" />

71
organize/job/README.txt Normal file
View file

@ -0,0 +1,71 @@
===============================================================
loops - Linked Objects for Organization and Processing Services
===============================================================
($Id$)
Let's do some basic setup
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True)
>>> from zope import component, interface
and set up a simple loops site with a concept manager and some concepts
(with all the type machinery, what in real life is done via standard
ZCML setup):
>>> from loops.organize.setup import SetupManager
>>> component.provideAdapter(SetupManager, name='organize')
>>> from loops.tests.setup import TestSite
>>> t = TestSite(site)
>>> concepts, resources, views = t.setup()
>>> loopsRoot = site['loops']
Let's also set up logging in a way that we get notified about problems.
>>> import sys
>>> from logging import getLogger, StreamHandler
>>> getLogger('loops.organize.job').addHandler(StreamHandler(sys.stdout))
Execute Jobs via a cron Call
============================
>>> from zope.publisher.browser import TestRequest
>>> from loops.organize.job.browser import Executor
The executor is a view that will be called by calling its ``processJobs``
method. As we haven't yet defined any job managers nothing happens.
>>> executor = Executor(loopsRoot, TestRequest())
>>> executor.processJobs()
We now register a job manager via an options setting on the loops root object.
As the corresponding job manager is not yet defined an registered a
warning is issued.
>>> loopsRoot.options = ['organize.job.managers:loops_notifier']
>>> executor = Executor(loopsRoot, TestRequest())
>>> executor.processJobs()
Job manager 'loops_notifier' not found.
So let's now define a job manager class and register it as an adapter for
the loops root object.
>>> from loops.organize.job.base import JobManager
>>> class Notifier(JobManager):
... def process(self):
... print 'processing...'
>>> component.provideAdapter(Notifier, name='loops_notifier')
>>> loopsRoot.options = ['organize.job.managers:loops_notifier']
>>> executor = Executor(loopsRoot, TestRequest())
>>> executor.processJobs()
processing...
Fin de partie
=============
>>> placefulTearDown()

3
organize/job/__init__.py Normal file
View file

@ -0,0 +1,3 @@
"""
$Id$
"""

40
organize/job/base.py Normal file
View file

@ -0,0 +1,40 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Base class(es) for job management.
$Id$
"""
from zope import component, interface
from cybertools.organize.interfaces import IJobManager
from loops.interfaces import ILoops
class JobManager(object):
interface.implements(IJobManager)
component.adapts(ILoops)
def __init__(self, context):
self.context = context
def process(self):
raise NotImplementedError("Method 'process' has to be implementd by subclass.")

56
organize/job/browser.py Normal file
View file

@ -0,0 +1,56 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Definition of view classes and other browser related stuff for job management.
$Id$
"""
from logging import getLogger
from zope import component
from zope.cachedescriptors.property import Lazy
from cybertools.meta.interfaces import IOptions
from cybertools.organize.interfaces import IJobManager
class Executor(object):
""" A view whose processJobs method should be called via cron + wget
in order to execute all jobs that are found.
"""
def __init__(self, context, request):
self.context = context
self.request = request
@Lazy
def options(self):
return IOptions(self.context)
@Lazy
def logger(self):
return getLogger('loops.organize.job')
def processJobs(self):
for name in self.options('organize.job.managers', []):
manager = component.queryAdapter(self.context, IJobManager, name=name)
if manager is None:
self.logger.warn("Job manager '%s' not found." % name)
else:
manager.process()

View file

@ -0,0 +1,15 @@
<!-- $Id$ -->
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="loops">
<browser:page
name="process_jobs.cmd"
for="loops.interfaces.ILoops"
class="loops.organize.job.browser.Executor"
attribute="processJobs"
permission="zope.Public" />
</configure>

26
organize/job/tests.py Executable file
View file

@ -0,0 +1,26 @@
# $Id$
import os
import unittest, doctest
from zope.testing.doctestunit import DocFileSuite
testDir = os.path.join(os.path.dirname(__file__), 'testdata')
class Test(unittest.TestCase):
"Basic tests for the loops.organize.job package."
def testBasics(self):
pass
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return unittest.TestSuite((
unittest.makeSuite(Test),
DocFileSuite('README.txt', optionflags=flags),
))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')