I am looking at WF4, workflow services, to implement business logic for a large system, using Appfabric & IIS/WAS for hosting.
Consider a credit-approval workflow:
- Customer Service rep (CSR) enters credit application into the system.
- Credit manager is to perform a credit check, and either Approve or Deny the application.
- So the Workflow Service waits for input at either the "Approve" or "Deny" WCF opperation, creating a Bookmark for each.
My question: How to I query for which Workflow Service instances are waiting on which bookmarks, so I can inform the users? I need to be able to bring up a list of workflow instances relevant to the user, and what state they're in, e.g:
- Credit Application #434: John Smith [Approve] [Deny]
- Order #1234: Possible Address problem [Verify Address]
etc.
Is there a central runtime or manager object I can query to retrieve WorkflowApplication references to Workflow instances?
So far, I've found these methods for dealing with this:
Keep a reference to each
WorkflowApplication, and callGetAllBookmarks()to get a list of active bookmarks. But in this case, Appfabric is starting/resuming my workflows - so I have no reference toWorkflowApplication. If I'm forced to start or resume each workflow instance manually, that makes Appfabric rather pointless.Query the Appfabric persistence table in SQL server directly. So if the schema ever changes, it's likely this code will break. Also means I have to deal with 2 databases simultaneously, with all of the latency issues that brings forth.
Recommended method: Use a custom tracking participant. As far as I can tell) none of the
TrackingRecordobjects emitted will tell you when a bookmark is set. There areTrackingRecordobjects emitted for change of state in aStateMachineactivity, but this would have two implications: 1. All waiting for input would have to occur within aStateMachine(not a showstopper, but very constraining), and 2. Having more than one wait state would get complex.
For anyone interested: The solution I chose was to use a completely separate set of tables in my own database to track which business operations are waiting on which users.
But it's not as bad as it sounds. I created a set of custom
Activityclasses/controls that have this functionality baked in.So instead of a standard
Receive/SendActivity, I use my ownReceive/Sendwhich, before waiting for a Receive, creates an entry in a table to say "Hey I'm waiting on User(s) A,B,C to take action X". Then when it Receives something, it deletes the entries for that workflow.Really annoying to have to go to this trouble. Microsoft has taken WF almost to the finish line then just stopped.