Thanks for your comments and thoughts.  Embedded below are some responses
about how the current thinking (of course, always subject to
change) addresses some of them -- if they do.

You might want to take a look at some initial code that has been checked
in to the "jakarta-commons-sandbox" repository, if you haven't yet.  The
easiest way to get this is to use anonymous CVS (you'll need both
jakarta-commons-sandbox and jakarta-commons to pick up dependencies), or I
can make snapshots available.

On Wed, 15 Aug 2001, John Sigler wrote:

> Craig,
> 
> Your Workflow Proposal seems like a great start. Several of us have
> played around with some workflow concepts on our current project but it
> would be great to have something integrated into Struts.
> 
> We have a few concepts that weren't mentioned that we think are worth
> considering:
> 
>   - "bookmarkable" workflow steps: This means being able to  
>     store all context related to a step in such a fashion that
>     the user can go back to that same the same state in the 
>     workflow at a later time. Bookmarkability should be 
>     optional (some steps may not make sense to be bookmarked) 
>     and so it should be able to be indicated as such when 
>     being defined.
> 

Hmm, technically every time that a Step tells its associated Context to
"suspend" (which causes the workflow engine to return control to the
calling app), that sort of acts like a bookmark -- in the sense that, the
next time this Context is executed, it picks up where it left off.  In a
web application, that happens each time you display a page and wait for
the response.  So, it seems we would need to provide a way for the user to
select a different in-progress activity (or start a new one), and then
come back to this Context later.  Does that sound right?

>   - a workflow "history": keep a state of where the user is 
>     and/or has been. Allow this state to be displayed as 
>     breadcrumbs, a history list, or with another visual or 
>     navigational representation. A tag to render this 
>     information seems useful as well.
> 

Supporting a breadcrumb trail makes a lot of sense, at least in some
applications (i.e. where you can legitimately branch to any of the
previuos spots).  There isn't any direct support for this in the current
code, although Steps can have an identifier (and thus be the destination
of a branch).

Managing a breadcrumb trail in some use cases is going to get interesting
... especially if the user can loop as well as nest.

>   - workflows, especially scripted workflows, will often be 
>     customized. The workflow configuration files should support the
>     ability to override a workflow definition - one possibility
>     would be to use a mechanism similar to a Java classpath. The
>     primary concern here is updating installations with new
>     versions of out-of-the-box workflows without overwriting any
>     customized versions of those workflows.
> 

This is an important point, and was raised in the jakarta-commons
discussion as well.  IMHO, this needs to be addressed at several levels.

* In the core APIs, the key component abstractions are Java interfaces
  (Activity, Step, Context, and so on) that can accomodate multiple
  implementations ... the usual object-oriented design approach, but
  lets customized workflow engines create their own implementations.

* Configuration of the static structure of a workflow Activity is
  separate from execution.  An XML format (as illustrated in the
  proposal) is one very nice way to do it, but you can build up your
  own structures as well.

* The point you are really making, though, has to do with the "registry"
  of scripted Activities.  There should be a hierarchical registry
  so that the Activity I get when I ask for the "Enter Purchase Orders"
  activity can be customized for me, customized for my department, or
  the standard one.  Is that what you had in mind?

>   - when a workflow is started, it should be associated with a
>     context that is specific to that *instance* of the workflow.
>     This supports the ability for a single user to execute the
>     same workflow multiple times simultaneously. In a web UI, this
>     is usually associated with a user opening multiple
>     windows. This implies that a workflow must have some kind of
>     instance id to uniquely identify its context and also makes it
>     clear that some kind of garbage-collection capability is
>     needed for workflows.
> 

The execution "instance" that I had in mind was the Context.  A particular
Context represents the current execution state (i.e. what Step is
next) plus all the associated variables (evaluation stack, plus variables
in scopes) of the particular user's execution of a particular Activity at
a particular time, while the Activity/Step object graph that I'm operating
against is a read-only description of the activity, and can be shared.

When thinking about it, I kept mentally picturing the execution unit of a
CPU, where the "next step" property is like the instruction pointrer, and
the evaluation stack is the stack frame, and the scopes are the
registers.  More than one operating system process can execute the same
(read only) copy of a program, because all their state info is kept
separate.

>   - the workflow configuration files/interfaces should support
>     i18n especially for labels since the labels will likely
>     appear in UI menus.
> 

I agree with the general philosophy, but there might be a couple of
different ways to look at it:

* The Activity/Step definitions themselves are never visible to
  the end user -- only the displays presented by the user interface
  will be.  Those definitely have to be internationalized, and can be
  (in the usual way, with <bean:message> and friends).  Where we
  still need linkages is when you *do* want to represent "goto
  destinations" in the activity as user interface items; that can still
  be defined in either the Activity flow or as part of the UI.  There
  are some more thoughts about this under your Struts integration
  questions below.

* There will be cases where the Activity itself needs to be customized
  based on who and where the user is (country-specific tax calculations,
  for example), that can be handled by customizing the overall flow
  (as we discussed earlier) or building conditional logic into a
  single flow.  The ability to do the latter is definitely in my
  thoughts -- in a Struts implementation, for instance, the Context
  implementation will have access to session-scope beans, so it will
  be able to see (or even set) the user's Locale etc., and use them
  for branching decisions.

>   - the ability to define pre- and post- conditions (inputs/outputs) 
>     for workflow steps would aid in robusting such as ensuring valid 
>     workflow definitions.
> 

Something that's not fleshed out in the sample code yet, but is very much
on my priority list, is pre-built Steps that can perform arbitrary
expression evaluation, conditional processing, goto, and so on.  These can
be used directly in a script, or you can also provide application-specific
Step implementations (using the namespace extensibility idea if you're
using the XML data formats) that do things in a nice compact way -- much
like Struts deals with calling validate() for you on ActionForm beans.


> A few basic questions that we have:
> 
>   - Can you give some more detail on your initial thoughts for the
>     Struts implementation? The types of questions I have are:
> 
>     o Where do Actions fit in with workflows/activities in
>       general? Are they used entirely behind the scenes when you
>       write the XML for an activity?  From the proposal
>       description, it sounds as if writing an Activity will not
>       require Struts coding... do this imply it will generate the
>       necessary Actions, etc?
> 
>     o Would things like Actions, ActionForms, and JSP pages need
>       to be written so they are "workflow aware"?
> 
>     o Are you thinking you'd extend ActionMappings to have another
>       layer where they can handle Activities or something else?
>       Here we're wondering if there's a way to retain the overall
>       model programming in Struts but allowing non-programmers to
>       create workflows.
> 

There are (at least) two major approaches to the Struts level integration,
and I haven't really decided which one I like better.  It would be
interesting to hear people's ideas.  I've given them arbitrary labels
below just to give folks something to refer back to in discussion.

(1) STANDARD ACTIONS APPROACH

* Struts would provide a single "standard action" class that interacts
  with the workflow engine.

* Each "workflow" supported by a Struts application would be mapped
  to a single action path, which (re)uses the same standard Action
  mentioned above.  So, starting a new Activity would mean just linking
  to a new Action URL - the fact that there was no Context in your
  session for this means you're starting a new one.

* The current execution state (i.e. Context) would be maintained in
  the user's session, so that multiple people can execute the same
  Activity at the same time.

* The JSP pages would be labelled with <forward> declarations as we do
  now -- the particular pages for a particular activity would have
  local <forward> declarations inside the <action> declaration for
  that activity.

* Included in the suite of built-in Step implementations would be the
  ability to call arbitrary methods of arbitrary bean instances, and
  pass arbitrary arguments.  Therefore, you would normally be able to
  dispense with writing an Action class itself, and either script the
  logic directly in the activity (certainly feasible for something
  simple like logon checking) or delegate to a business logic class
  or EJB just like an Action does now.

* JSP pages would be mostly independent of the fact that they are being
  operated inside an Activity.  However, a linkage is required in order
  to provide navigation controls for branch points.  Therefore, the
  Struts integration layer will provide a custom tag library that
  includes tags like "branch to step XYZ" when a button is pushed, or
  a link is followed.  Even though all of the "real" HTTP transactions
  would flow back through the action URI for the activity you are
  executing, the associated parameters would tell the workflow engine
  what to do next.


(2) APPLICATION ACTIONS APPROACH

* Workflows would be "assembled" out of existing actions and pages.

* Individual actions would need to consult the workflow engine to
  determine where to go next, rather than deciding for themselves.

* A Context object in the user's session would be used to maintain
  current execution state of an activity, but there would definitely
  need to be a way to support more than one.

* Pages would need to have mechanisms to create navigation links
  (the same custom tag library mentioned above).

* Would rely on computational and navigation logic being performed
  in Actions (as Struts-based apps do it today) more than in the
  Scripts.

TRADEOFFS

* Buying in to the Standard Action approach means that it *must* be
  possible to perform anything you might do in an Action, either
  directly in the activity's script or by delegating to business
  methods through the "arbitrary invoke" feature.  I believe that
  is feasible, but it bears more thought.

* Standard Actions approach tries to abstract the control flow of
  an Activity away from application components, letting them focus
  on "pure" business logic.  Application Actions lets the app
  developer participate in this, in app-specific ways.

* When retrofitting an existing Struts app, both approaches would
  require modifications to the JSP pages (to present navigation
  choices in a manner that the workflow engine can recognize).
  For Actions, you'd be totally replacing them (in the Standard
  Actions approach, or modifying them to delegate their control flow
  decisions (in the Application Actions approach).  Which one is
  simpler depends on how careful you were in making your Actions
  do *only* control flow, and delegating the real work to business
  objects -- which can be happily reused under either approach.

* In the Standard Actions approach, the workflow engine directly
  participates in every request processed for that activity (in a
  sense, it becomes a mini-MVC-controller).  Therefore, it is less
  likely to "lose control" of the user interaction due to application
  developers errors or misunderstandings.  The Application Actions
  approach will rely on Actions to be good workflow citizens and
  *always* delegate control flow decisions back.

OPEN ISSUES

* How does a user initiate a particular Activity (from the point
  of view of the workflow system).

* Nesting of activities (if you're an old-time BASIC hacker,
  think GOSUB and RETURN :-).

* Single user can open multiple windows and execute several
  activities (i.e. with separate Contexts) at the same time.

* How to prevent a malicious client from using the navigation
  control inputs to attempt to bypass Steps.  Maybe use the
  transaction token scheme universally and transparently.

* Security issues in general (who can execute a particular flow?
  can he/she do all the steps or just some?) need to be fleshed
  out, and built-in Step implementations provided to support
  such decisions.

* None of the discussion above has dealt with the "Process" abstraction
  where the ideas include longer execution timeframes, asynchronous
  events, and collaboration between users.  Right now, I'm thinking
  that Processes will be composed on top of Activities, but there
  might be some Process-based requirements to keep in mind as we
  design the Activity layer.

As you can probably gather from my descriptions, I'm currently leaning
towards the Standard Actions approach to this.  As appealing as it would
be to use existing (or newly created) Action implementations, I'm
concerned that the end result will be fragile -- primarily because Action
developers are used to managing their own control flow, and there are
probably many scenarios where these control flow decisions are too complex
to be encoded in a simple workflow script.

That being said, of course, under absolutely *no* circumstances would I
contemplate de-supporting the current Action machinery.  Way too many
people are building apps based on Struts 1.0 -- and they are all over the
world, so I wouldn't have any place to go hide even if I tried :-).

More seriously, workflow isn't going to solve all application design
problems.  I suspect there will still be a need to create new apps that
still need the complete control that actions give you over things.  But I
also believe there is a sweet spot for activities with relatively simple
flow (filling out a wizard form, for example) that are tedious to write
using just Actions, and we can make Struts-based development of such
applications much simpler by abstracting away the navigation machinery.


>   - Do you think browser issues can be handled properly? Caching
>     has caused us problems in the areas of handling back, forward,
>     refresh buttons... for example, the previous page displays
>     correctly but the actual state of the workflow has not been
>     updated due to the page being cached and the context state is
>     incorrect.
> 

The current Struts approach to this (setting or not setting the cache
control headers) is pretty crude, but having a workflow gives us the
opportunity to be more fine-grained about those decisions.  Coupled with
aggressive use of transaction tokens, I *think* we can handle most of
these concerns, but we'll always need to keep this in mind.

> thanks,
> john sigler
> 

Craig


Reply via email to