I'm relatively new to using Windows Workflow but we have a requirement whereby all currently active workflows undertake an action based upon a "global event" rather than an event based upon a single instance.
e.g. you could have a workflow which is used for the submission and tracking of tickets, with the scenario that when the support desk goes home all of the active workflows generate an e-mail to the person who submitted the ticket saying that their ticket won't be looked at today.
What is the best approach to do this?
Is it a custom activity or some other method of enumerating all of the active workflows and firing an event/queueing an item to the workflow queue?
Clearly from the workflow perspective it would be nice to have an activity within it which is fired when, in the case of the example above the office closes.
All input gratefully received.
It depends on how you are hosting your workflows. Using workflow services and WCF messaging is by far the easier option and would be my preference.
Assuming you are using workflow services with persistence enabled you can easily get a list of each workflow instance from the store so you can send the WCF message to them. Using the active bookmarks in the instance store you can actually see if the workflow supports the operation in question at the moment.
If you are self hosting using things are a lot harder ad you will need to create a custom activity with a bookmark to handle this. But assuming workflows can be unloaded from memory you will need some external code to reload the workflows.
BTW workflow queues are a WF3 feature that has been replaced by bookmarks in WF4.
One way to do this would be to get the application hosting the Workflow Runtime to enqueue a work item into the workflow queue. All activities that need to respond to this stimulous must have bookmark for this queue.
Related
I’m building a project that allows the user to send notifications to his customer.
I want the user to also be able to schedule these notifications to run at a specific time instead right now.
How would I achieve this? What’s the best structure? Should I create a cron job that hits the server every second to check if a task is set at this second?
You can create your own code that runs the tasks by a schedule, but there are already several 3d party tools for that. I would recommend you to have a look at
Hangfire or Quartz.NET
I would recommend to capture the details from your customer but in the backend pass on the details to the logic apps or power flow which can be timer based to create a job within those apps. I would recommend power flow as you can use it out of the box where as for logic apps you may have to configure logic apps first. as you tagged the question to Azure i am guessing you are using azure stack.
if not above suggestion may not work for you.
I have been looking around for a while now and I want to create a timeout property on a bookmark in WF 4.0.
I can make it work with using a Picker with two different branches (and have a timer in one of them and my bookmark in the other).
However this does not work if my workflow is persisted to the database (which it will be since the timeout will be several days) since it will not trigger until i load the workflow next time which can be several days also.
Does anyone know if there is any other way to solve this in the WF 4.0? Or have you done a great workaround?
Okay so what you're going to want to do is build a Workflow Service, you will not be able to do this via a workflow that is not hosted via the Workflow Service Host (WSH) near as easily. To tell you it can't be done would be incorrect, but I can tell you that you don't want to.
That service will be available via a WCF endpoint and can do exactly what you're needing. You would be able to build a workflow that had a pick branch that had two things in it, the first is a Receive activity that could be called into by the user if they responded in time. The second would be a durable timer that ticked at a specified interval and would allow you to branch down another path. Now this same service can have more than one Receive activity and thus exposing more than one endpoint so if your workflow has any other branches just like this you can handle all of those in one atomic workflow.
Does this make sense?
I have a little trouble deciding which way to go for while designing the message flow in our system.
Because the volatile nature of our business processes (i.e. calculating freight costs) we use a workflow framework to be able to change the process on the fly.
The general process should look something like this
The interface is a service which connects to the customers system via whatever interface the customer provides (webservices, tcp endpoints, database polling, files, you name it). Then a command is sent to the executor containing the received data and the id of the workflow to be executed.
The first problem comes at the point where we want to distribute load on multiple worker services.
Say we have different processes like printing parcel labels, calculating prices, sending notification mails. Printing the labels should never be delayed because a ton of mailing workflows is executed. So we want to be able to route commands to different workers based on the work they do.
Because all commands are like "execute workflow XY" we would be required to implement our own content based routing. NServicebus does not support this out of the box, most times because it's an anti pattern.
Is there a better way to do this, when you are not able to use different message types to route your messages?
The second problem comes when we want to add a monitoring. Because an endpoint can only subscribe to one queue for each message type we can not let all executors just publish a "I completed a workflow" message. The current solution would be to Bus.Send the message to a pre configured auditing endpoint. This feels a little like cheating to me ;)
Is there a better way to consolidate published messages of multiple workers into one queue again? If there would not be problem #1 I think all workers could use the same input queue however this is not possible in this scenario.
You can try to make your routing not content-based, but headers-based which should be much easier. You are not interested if the workflow is to print labels or not, you are interested in whether this command is priority or not. So you can probably add this information into the message header...
In a project that we are using WF4, it is a requirement to show our users a friendly list of the steps of the workflow (the logical steps from the users point of view, not the technical steps) along with each step's status ( like a big green check mark if the step has been completed).
I'm wondering if this is something that Workflow tracking should be used for or not. My impression from what I have read about workflow tracking is that it is really more for technical logging.
The alternatives would be persisting an ordered list of steps and their statuses along with the workflow or outside of the workflow.
Either way I'm fuzzy about how this should work and appreciate suggestions.
Workflow Services would be very useful for you. This is some sort of convergence point between wf and wcf and used to marshal WCF services calls to WF instances. You can create a duplex channel and receive updates via callback channel.
You can use workflow tracking to register activity execution and use the WorkflowDesigner to show the progress to the user. There is an example of how to do this in the WF4 samples from Microsoft you can find here.
For a client the system we're creating must support the following:
- It must be possible to run multiple workflows, and multiple instances of the same workflows with a different context (different data/business objects).
- Some workflows will be long-running, involve multiple users/client session and waiting for external user input. So the workflows must be able to be persisted and respond to some signal from a client app. And it also means that the execution of workflows must be done on a server app (right?).
- I want to be able to run all kinds of workflows on the server app, and I do not want to have to re-deploy the server app when a workflow changes.
My first thought was Workflow Services. After a lot of research I concluded that this is not the right path since Workflow Services basically gives the possibility to execute activities at a remote location from a workflow started in a client app. Is this correct? Or can I use Workflow Services for the scenario above? Most examples and/or tutorials are basically a ReceiveSignal/Send combination with some logic in between.
Basically I want to initiate (from a client app) the start of a workflow with a specific context (in the workflow server app).
What is the best approach?
Any help is very much appreciated!
As for your requirements:
It must be possible to run multiple workflows, and multiple instances of the same workflows with a different context (different data/business objects).
This is no problem with WF.
Some workflows will be long-running,
involve multiple users/client session
and waiting for external user input.
So the workflows must be able to be
persisted and respond to some signal
from a client app. And it also means
that the execution of workflows must
be done on a server app (right?).
WF is designed for long running tasks that can interact with outside influences. However, that doesn't say its easy to accomplish; there is no universal solution which you can hook into. You will probably have to design custom Activities that interact with Workflow Extensions which handle moving user input into the workflow. Same with exposing the workflow to the outside, although WF4 does come with a host of WCF activities which could be used to accomplish this.
I want to be able to run all kinds of
workflows on the server app, and I do
not want to have to re-deploy the
server app when a workflow changes.
This is harder to accomplish. You must, at a minimum, separate the workflows from the server code. The simplest route is to store your workflow as xaml and load it at runtime from, say, a database.
Other options are to use some kind of dependency injection framework (such as Structure Map or Unity) which loads the workflow assembly at runtime. If the workflows change, you can drop the new assembly on the server, change your config and restart. Alternatively, you can isolate your workflow assemblies within their own AppDomain, load them at runtime and throw away the domain when you must reload a new version. Which one you do depends on your requirements; I'm actually doing the third option as I have to load many different versions of workflow assemblies at runtime, run them concurrently, and they often have embedded resources thus preventing me from going the XAML route.
My first thought was Workflow
Services. After a lot of research I
concluded that this is not the right
path since Workflow Services basically
gives the possibility to execute
activities at a remote location from a
workflow started in a client app. Is
this correct?
I'm hosting my workflows within a standard Windows service application. I have to manage and maintain the WCF frontend which the client uses to interact with my workflows. As far as I can tell, Workflow Services seems like a viable option for stable workflows, if I understand it correctly. Hosting an application in AppFabric is also a good option, and I believe simpler than using a Windows Service. But no matter what the host is, you have two options--your workflows define your service contract, or you must define the service contract and handle all execution and communication with workflows you are managing.
The first is a good option for stable workflows with a simple facade. It doesn't seem like a good option for you, as you must load workflows dynamically as they change; that requires logic outside of the workflow to handle not only communications from the client ("here's a new version of workflow X!") but also managing the workflow lifespan.
It seems like you will have to find some kind of host application (IIS WebService application, Windows Service, AppFabric, Azure), define your WCF service and bring it online, handle calls from clients, communicate these calls to your workflow running code, which then must load and execute these calls and return the result up the chain.
I can't help but notice that you seem slightly ill-prepared for the journey that awaits you. I would strongly suggest creating a prototype that slices neatly through the centermost meat of your requirements. A hosted application (I'd suggest AppFabric) with a WCF frontend that loads a XAML-based workflow that processes client calls. Once you have the simple version nailed down, you can widen the scope to encompass all your requirements.