HI cedrick

> To solve this « pb », just create WADynamicVariable as a subclass of
> DynamicVariable already in Pharo.

Ok I will do it. What is important is to *share* knowledge and code.
So I changed and publish the code in my branch to make
CurrentWorkflowManager an dynamic variable.
Before I just inherited from Object.
Now we get a version that can be loaded.


There are also missing part for the
> export/import in XML (should be easy to fix and Max propose to give the code
> - DOMBuilder and co.)
> I tried to start a booklet with Stephane but it is too complicated right
> now. Stephane started a simpler version.

For now saving and loading is not important. :)


> I put below a summary of the reflexion/discussion I had with Max.

Thanks.
Now you should publish your code.
I would have preferred to work from a working code. Because now it is
like poking in the dark.

Cedrick what did you get running?

Stef
Some comments below


> ========= INTRO
>
> What's missing compared to the full (proprietary) solution are user
> interfaces that were web based (Seaside \+ Magritte). Also, persistence was
> achived through Omnibase. References were removed but they are stil some
> disfunctionning. Moreover, the completion of activities were mainly manual
> and achieved through web interface (web forms). They are, for now, no real
> way to introduce different kind of activities like those being
> message-based, event-based, service-based.
>
> To evolve, one has to remove all dependancies to Omnibase and
> Magritte/Seaside.
>
> There are also important design decisions to ensure WfWorkflow being a
> powerful and extensible workflow management system for Pharo. To me there
> are 2 main tasks:
> - rethink persistence (process definition and orchestration, realization)
> => persistance is essential and was central to Aare. Beside removing
> Omnibase references (and implication of WfManagedObject), some of the
> application features were very dependant on the persistence (like logging,
> tracing process evolution). All of these features are to be thing again
> considering as much as possible a loosely coupled solution. A general
> purpose storage solution like Voyage could be used. At first, in image
> storage will be used to focus on the running aspects of the library.
> - rethink interaction
> => Designing a general interaction sub-system is probably the more
> challenging tasks. Aare was web based. We want workflow to be UI agnostic.
> Moreover, we want to associate  ,
> remove Magritte (replace UI or build an independant system based on
> Annoucement for instance)


Yes I agree. Now I would like to be able to
- define a super simple workflow: I picked sequence: start -> task1 -> task2
- execute it and script it resolution.

I would like to understand the difference between frame and activation.

> ========= RANDOM QUESTIONS AND ANSWER (in black me - below max)
>
> 1)
>
> The static definition of workflow is done through WfWorkflow, WfOutgoingEdge
> and WfSteps (+ WfConditions). The easy part :)

Yes the easy part.
I started to add a test to cover his

>
> The runtime aspect are achieved via WfActivation, WfWorkList,
> WfWorkflowHistory et WfWorkflowManager. More difficult to understand and
> make evolve.
>
> WfWorkflowHistory represents the different versions of a workflow, so it
> belongs to the static part.

I saw and documented the interaction between a workflow history and
its workflows.


WfWorkflowManager managers workflow definitions
> (static) and activations (dynamic).
> WfFrame is also a part of the dynamic side, connecting activations to a
> workflow.
> Workflows are hierarchical, i.e. a step can have a sub workflow (see
> WfWorkflowLibrary>>simpleSubflow)

Yes for now I do not want to understand this part.

>
> 3)
>
> Going back to activations, here is my current understanding.
>
> Once a step is activated (all condition on Edges leading to are true - to
> evaluate outgoing conditions of a step, the step execution has to be
> complete first) , we get an activation instance (I’m not 100% sure how
> completion of an activity and outgoing conditions are managed).
>
> As far as I understand, a step can always be activated (e.g. manually).
> However, activating a step propagates the values of conditions on the edges
> to the next steps and their activations ("dead" or "alive"). Hence, an
> activation responds to #isAlive with true if at leat one incoming token was
> true ("alive") (see WfStep>>continueInFrame:fromStep:alive: and
> WfActivation>>isAlive). The conditions are evaluated once #complete is sent
> to the activation.
> Activation instances are created by two ways (slightly different for the
> start step), but generally they are created when a step receives tokens from
> the outgoing edges of an upstream activation (see
> WfStep>>continueInFrame:fromStep:alive:).
>
>
> On the exemple of BLActivationHistoryItem that you gave, I’m not sure if
> it’s an activation of a history item stored in the history (subclasss of
> WfHistory?).
>
> My idea was that it should represent a record for an activation (there might
> be multiple records for a single activation). So "HistoryItem" would be the
> general description of a record, of which "ActivationHistoryItem" is a
> special case for activations (I hope that makes sense).
>
>
> 4)
> Moreover I don’t see clearly the difference with a scheduler and a BP engine
> (they are at least really complementary). Do you see any ressemblance
> between Activation and ScheduledJob ?
>
> I actually would like to have a (simple) scheduler with the BP engine :)
>
> Well, it's certainly a matter of point of view. I would argue that an
> activation is something close to a "job". A "scheduled job" would be a more
> specific case of a "job", a job that is in a queue. An activation has no
> notion of scheduling but simply represents the idea of what happens when
> traversal between two nodes occurs. A scheduler would be one way of managing
> activations (WfWorklist seems pretty close to a scheduler, holding running
> and completed activations).


Too subtle for me.


> To me the scheduler right now is not really existing besides having a list
> of simultaneous/parralelized steps to realize (activated or not). Activated
> means currently being done.
>
> You're right, I think. The application that Workflow was designed for
> required manual interaction, hence there was no need for other methods of
> scheduling (e.g. by time or event).
>
>
>
> This activation role is about logging and interacting with responsible
> users. But it is more than that. It’s the actual job being done.
>
> Yes.
>
>
>
> 5)
>
> Concerning run time modification of a process. Is it true that we can modify
> a currently executed workflow (steps that are not yet activated ?) ? I think
> that is possible (an cool). When activated, it shouldn’t. Would you think it
> would be interesting to allow activations to be suspended/resume (frozen),
> cancelled ?
>
> The history of workflows consists of copies. The steps of a workflow
> reference the workflow they belong to. Therefore, while it is possible to
> modify a workflow, modifications do not impact running workflows, as the
> steps of that workflow continue to reference the previous version. The model
> suggests that it is ok to create a new version of a workflow but not to
> modify existing workflows.

For now I would like to get a workflow running without modifying it


> The model does *allow* (in principle) to modify an existing workflow but I
> doubt that was the intention.

I think that it was because else why to bother.

However, I don't see why modifying an existing
> workflow has to be bad thing, as long as you can guarantee that only edges
> and steps are modified that have not yet been activated. That could open up
> some interesting possibilities.
> Cancellation of an activation could be very interesting. It would basically
> allow reversal of complex effects. Very nice idea! I'm not so sure though
> whether suspending makes much sense. Maybe when a step has the potential to
> take a long time for some operation. But then you may run into transaction
> problems. The nice thing about an activation at the moment is that it's
> atomic (in theory). But again, done right that could open up interesting
> possibilities.
>
>
>
> If a running process is modified, do we track its evolutions in
> WfWorkflowManager ?
>
> The modification of a workflow is indeed announced to WfWorkflowManager,
> yes. Workflow versions are stored in WfWorkflowHistory. For modifying a
> *running* workflow you will probably want to create a specific workflow
> manager for that, that does validation etc.
>
>
>
> The goal of history(s) are to log the realization of the process. But is it
> one of its aim to « replay » the process execution ?
>
> No. WfWorkflowHistory only stores the static definitions. However, the
> history of activations could be used to replay an execution (nice idea!).
>
>  i.o.w.,  Is it more than log/report ?
>
> I think the activation history was designed as a log, the workflow history
> as a log and also as a way to undo changes. As you suggest, however, they
> could certainly be used for more things.
>
>
> I agree with the separation (WfWFManager for the run time evolution of the
> process definition => adaptation    and WfActivationHistory for the trace of
> interactive/automatic step realizations information).
>
>
> #beginHistory implementation example was very helpful. I knew I missed
> something  Just, as I see a MailManager (with role is obvious), is it
> something that has to be generalizable ? Like InteroperableManager ?
> MessageManager ? To get user interactions
>
> That would be very nice, yes. You're completely free to do what you like. It
> would be cool though if we could evolve the project as opposed to you
> creating a fork to your own liking. If you're game we can set up a workflow
> on github where you open pull requests against our repository.
>
>
>
> 6) I’d like to remove fully the reference and need of Omnibase and
> Magritte/seaside forms.
>
> Yes please!
>
>
> I think Omnibase is ok, even storing in image for instance.
>
> What’s more problematic to me is for user interactions (and even automatic
> interaction through program for instance). There are achieved in your
> example with seaside. It is ok but what if I’d like to do it more generally
> ? Would we use Annoucement for example ?
>
> I think that is completely open to implementation. In my eyes, Workflow
> should remain a separate library that does not enforce any kind of specific
> presentation or persistence. What's critical for that is of course the right
> kind of interface.
> Announcements would certainly be an interesting way to decouple Workflow
> from other parts of the system.
>
>
> I’d like to have an incomingMessageBox for each user and eventually
> transform these message in concrete action (user i/o) ? Or dispatch in
> JobQueues (each user being a distant worker thread). Again, the distinction
> between Scheduler and BPEngin is fuzzy to me.
>
>
> Does it make sense to you ?
>
> Yes, it does :) What I've asked myself (out of curiosity) is whether you
> want to have
> - a dedicated instance for executing workflows
> - a distributed workflow with autonomous synchronisation (parts of a
> workflow could run on every uses instance, others would need to be executed
> through agreement)
> - a partially distributed workflow with one or more managing nodes that
> control the core steps (e.g. you could designate parts of a workflow as
> independant)
>
>
> PS: some random comments on your proposals
>
> Parts of Workflow were never cleanly separated from the proprietary
> application, so there are indeed a couple of things that are missing (mostly
> #subclassResponsibility stuff etc.)
>
>
>
> - initializeDefaults is not present for steps but thats ok.
>
>
> - in #createIncoming: (doesn’t exist), I don’t get ….. => makePersistent
> asPersistentReference.   You store persistentReference of steps. Is it like
> the step object itself ?  I would store the step objects (as no persistance
> right now).
>
> An activity step is a specific subclass of a step. Such a step includes
> additional information such as documents, duration and user roles. I'm not
> sure why "makePersistent asPersistentReference" is sent there, as WfStep
> already inherits from WfManagedObject and would, therefore, already be
> managed by OmniBase. But I don't know OmniBase, maybe some things need to be
> announced specifically.
>
>
> - I don’t understand the offsetSeconds in your BLActivationHistoryItem
>
> That's really just some business rule to modify the timestamp of the history
> item.
>
>
> ============= Others responses from Max
>
> WfWorkflow - Load and Run
> All instances that inherit from WfManagedObject were managed by OmniBase,
> yes.
> DomBuilder is a small package for wrapping XML-Parser. I'll publish it so
> you can use it.

Cedric did you got this package?


The XML-Parser package has been significantly modified and
> is now named XMLParser (you can find it in the catalog). You should make the
> changes necessary to use the current incarnation of XMLParser (decide for
> yourself whether you still need DomBuilder or not).

But this is not really important.

>
>
> Those IDXXX classes belong to another package a didn't publish (but will).
> This package also includes an OmniBase specific class.
> Magritte has changed significantly over the years but the core should be
> pretty much the same. Just load the newest Magritte and try working with
> that.
>> ok but avoidable ?
>> try loading Magritte ?   Long …
>
> #beginInHistory should be implemented with #subclassResponsibility on
> WfActivation.
> Your explicit implementation could then look something like this:
> beginInHistory
> self history add: (MyActivationHistoryItem new
> message: 'started';
> user: (WACurrentSession value
> ifNotNilDo: [ :session | session user ]);
> type: #started;
> yourself).
> MyMailManager noteNewActivation: self
>
> Basically, what the history contains is up to the workflow implementation. I
> think it would makes sense though to have an abstract
> WfActivationHistoryItem.
> WfActivation>>history should be implemented like this:
> history
> ^self propertyAt: #history ifAbsentPut: [ OrderedCollection new ].
>
> Although I think that it would be good to have a dedicated
> WfActivationHistory class. WfWorkflowHistory is associated with changes to
> the workflow, not activations. Both history classes should probably inherit
> from an abstract class WFAbstractHistory.
>
>
> Seaside interaction
>
> Here are a couple of action implementations in Seaside components that
> should give you an idea of how to interact with the workflow:
> MyActivationComponent>>complete
> self activation hasCompleted
> ifTrue: [ ^ self ].
> self history add: (BLActivationHistoryItem new
> message: 'completed';
> user: self session user;
> type: #completed;
> offsetSeconds: -1;
> yourself).
> self activation complete.
>
> MyActivationForm>>accept: aString
> self activation authorized: true.
> self history add: (BLActivationHistoryItem new
> comment: aString;
> message: 'accepted';
> user: self session user;
> type: #accepted;
> offsetSeconds: -2;
> yourself).
> self completeIfSatisfied.
>
> MyActivityList>>addActivity
> self call: (MyActivityEditor new
> workflow: self workflow;
> yourself).
> self refresh.
>
> MyActivityEditor>>buildActivity
> ^(self workflow newActivityStep
> initializeDefaults;
> yourself)
> asPersistentReference.
>
> MyTransitionEditor>>createIncoming
> | step |
> step := (self workflow newActivityStep
> initializeDefaults;
> yourself) makePersistent asPersistentReference.
> self addIncoming: step.
> MyCurrentWorkflowComponent value showActivity: step.
>
> MyTransitionEditor>>addIncoming: anActivity
> ^self add: anActivity to: self activity.
>
> MyTransitionEditor>>add: aSourceActivity to: aDestinationActivity
> ^aSourceActivity addOutgoingEdgeFor: aDestinationActivity.
>
> MyTransitionEditor>>editCondtions: anEdge
> | component |
> anEdge condition isTrueCondition
> ifTrue: [ anEdge condition: WfAllCondition new ].
> component := (MyConditionEditor activity: self activity)
> container: anEdge;
> addDecoration: (MyToolbarDecoration new
> title: 'Edit Transition Conditions to: ' , anEdge to name;
> toolbar: [ :html |
> html
> icon: 'icon_close.gif'
> text: 'Close'
> action: [ component answer ].
> html helpIconOn: component ];
> yourself);
> yourself.
> self call: component.
>
> MyConditionEditor>>addRule: aDescription
> | new |
> new := MyCondition newPersistent
> field: aDescription;
> asPersistentReference.
> new := self call: (self
> buildEditorFor: new
> titled: 'Add Rule for ' , aDescription asLabel).
> new isNil ifFalse: [
> self condition add: new; markDirty.
> self changedForm ].
>
>
>> WfWorflowManager class is empty defining empty stubs/protocols. Its aim
>> seems to be about “logging/noting” changes. Is is it’s only role ?
> Correct. You would use WfWorkflowManager to update the workflow in OmniBase
> (e.g. mark dirty, add new activation etc.). #generateID would generate an ID
> from OmniBase and #activationClass would answer your specific activation
> class, if you choose to override WfActivation.
>

Reply via email to