[Zope3-Users] Re: [Zope3-dev] Community opinion about workflow
engine
Stephan Richter
srichter at cosmos.phy.tufts.edu
Tue Mar 13 09:13:38 EDT 2007
Hi Godefroid,
CCing zope3-users, where this post belongs to.
On Monday 12 March 2007 11:48, Godefroid Chapelle wrote:
> - about the existing workflows (DCWorkflow, Zope3.wfmc, AlphaFlow,
> OpenFlow...)
Kit asked the question about workflows on the SchoolTool list as well; I
assume that you guys are working together.
I have personally found that workflow engines are ususally overkill. In fact,
I think document/content publishing as it is done in Zope 2 CMSs is one of
the exceptions.
In SchoolTool we decided early to use a workflow engine to enforce process. We
have found there that it was overkill. (Everyone else can read Tom's comment
on the SchoolTool-Dev list.)
That said, here is my experience from another customer. This customer asked us
to rewrite a job application management software. You can easily see the
common workflows there. However, her complaint about the old system was that
the workflow was too stiff and she wanted to change the list of stati of a
particular application at any time manually, effectively breaking the
workflow.
With those requirements in mind we looked at our options, and she wanted to
deliberately break the flow we decided against any workflow engine. Instead,
we implemented stati as a special property of the application. Whenever the
stati are changed, we fire events for each added status and another event for
each removed status. We then created a module called "policy" that contains a
multitude of event subscribers listening to the events and doing the work.
Those tasks include writing logs, sending E-mails, triggering other status
changes, security changes, and data verification. Here is some of the
interesting code:
application:
class Application(Contained, Persistent):
...
@apply
def stati():
"""See IApplication"""
def getStati(self):
return self._stati
def setStati(self, value):
removed = set(self._stati) - set(value)
added = set(value) - set(self._stati)
self._stati = tuple(value)
for item in removed:
zope.event.notify(StatusRemovedEvent(self, item))
for item in added:
zope.event.notify(StatusAddedEvent(self, item))
return property(getStati, setStati)
policy:
@zope.component.adapter(interfaces.IStatusRemovedEvent)
def historyApplicationStatusRemoved(event):
log(
event.object,
_('Status Removed: $status', mapping={'status': event.status}))
# Not reacting to a status change, but nevertheless interesting to look at.
# Yes Martijn, I love hurry.query!
@zope.component.adapter(interfaces.IApplicationCompletedEvent)
def applicationCheckForDuplicate(event):
# When upon completion of the application, another application with same
# last name, first name and birth date is detected, then this application
# is marked as duplicate
app = event.object
duplicateQuery = query.And(
query.value.Eq(('app-catalog', 'firstName'), app.firstName),
query.value.Eq(('app-catalog', 'lastName'), app.lastName),
query.value.Eq(('app-catalog', 'birthDate'), app.birthDate),
query.query.Not(
query.set.AnyOf(('app-catalog', 'stati'),
(interfaces.INCOMPLETE,))
),
)
result = tuple(query.query.Query().searchResults(duplicateQuery))
# Only mark applications as duplicates, if the application is not itself
if (len(result) == 1 and app not in result) or len(result) > 1:
app.stati += (interfaces.DUPLICATE,)
So in fact, our workflow engine is the Zope 3 event framework. I like it for
the following:
- There is no new framework overhead; use what you know.
- It is maximally flexible. I have control over the way I implement the
business logic and the UI.
- Having all policy in one place (this includes event subscribers to other
events as well) provided great oversight. Whenever the customer asks
me: "What are the rules for this behavior?" (even though she specified it, of
course), I can just go to this one place and give her an answer within a few
minutes.
- Easy to test. It is very simple to test each event subscriber in isolation
and go through all the cases.
I guess I would not have to say it again, but I really like this pattern.
Regards,
Stephan
--
Stephan Richter
CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student)
Web2k - Web Software Design, Development and Training
More information about the Zope3-users
mailing list