I got this down to a minimal set.

First, the symptoms (I'll explain later why I'm trying to do this ;) )

If I try to close out of an activity in the On Ready, the close seems to hang.

Close Early Process


Close Early Process
On Ready:

If you put a breakpoint on the CloseCloseEarlyActivity action here, when you click a button and have it LaunchCloseEarlyProcess, it will stop here. If you then try to Continue or Step Over, it contemplates this for a while and then comes up with the error:

Error diagram

Even without the debug, it does not appear to continue, as I found in other testing.

Now, as to the WHY I am doing this.

If you want to close an activity, you need the Activity ID. If you grab the Activity ID from the activity before the Human Activity and remember it somewhere, then it's the wrong ID to use for the Close Activity call.

On Ready is the only place you can grab the Activity ID, record it and use it to close the Human Activity from elsewhere.

I was hoping that in the On Ready, if it was determined that there wasn't enough work for the recipient of the Human Activity to do, I could call Close [Activity] and just continue on with the process.

(Additional note - this is in If it got fixed in 9.1.x, I would also be happy :) )

-- Ritchie Annand
Hi Ritchie,

This type of errors while dealing with BPT are usuale related with the fact than in BPT everything is assynchronous and handled on different transactions. For example in a screen if you want the values you just save on the DB to be available in an activity you need to explicitly put a commit.

You've explained the "technical why", but why closing a human activity explicitly when it's beginning. A human activity should be closed "by a human".

I don't know exactly but you must have a perfectly valid use case that on a certain condition needs you to close it. If that's the case you should model your flow to bypass the actvity all together so the process doesn't stop.

Typically human activities can be closed explicity for the flow to continue but that's after a certain time and for that you have the "Close On" property.

Hope this helps
True, and I'm taking explicit advantage of that asynchrony.

That said, unless I miss my mark, the events do not occur in an asynchronous fashion... that is to say, it has to wait for the duration of the event handler because it is guaranteeing not to continue on past the Ready state until the On Ready has run.

It would be nice to effect a valid state change from a handler (valid as in allowed by the diagram).

Ready to Close

I think it probably just comes down to implementation. If you call Close [Activity] from outside the process, it queues that up and handles it as soon as possible. From inside the handler, Close [Activity] should switch the state directly, or at least handle the state change as soon as it comes back from the event handler (a queue without a wait?). I imagine that dragging Close [Activity] into the event handler calls exactly the same code as dragging it externally, and I'll bet there's a lock or wait or timed request in there that can't actually be handled while inside the event handler.

As to the "why", in this case we have an asynchronous piece that can be optionally automated: an agent essentially pretending to be a human can come along from another server, grab some work and then call a "work complete" web service which closes the activity. That Close [Activity] needs the proper Activity ID, which I store in the On Ready so that the automated agents can give them back during the "work complete" call.

If I replace the Human Activity with a Wait Activity, I get "Activity 'WaitCloseEarlyActivity' (#....) is already being processed." I guess that's more definitive than a hang, but...

I can split this up; it's just a pain. I'll have to do most of the processing in an Automatic Activity, throw a Decision in to skip it, and track down the entries I made in the Automatic Actiivity and add the ActivityId to the data row in the On Ready of either a Human or a Wait Activity.

Bleah. I was just hoping for a state change :)

Cheers, Guilherme!

-- Ritchie
Ahahaha, okay, a hack is a hack, but this ended up working:

...instead of calling Close [Activity] from within the On Ready, I launch another Process, passing the current ActivityId and get that to do the closing for me.

Now my no-work cases continue on with the rest of the process like I was hoping.

(I was about prepared to use timers. The alternative was running my queuing code twice, once "fake" - to get a count - and once "real".)

-- Ritchie
A clarification on the hack and a little worry that there might be a race condition involved: starting another process to close the current activity only worked consistenty if it was the very last thing done before the End.

Otherwise, you get the error that it's already being processed.