- If software is a server application, part of being great is scaling well, handling large loads without consuming too many resources.
- A great application should also be as easy as possible to understand, both for its creators and for the people who maintain it.
- Approaches that help applications scale tend to break them apart, dividing their logic into separate chunks that can be hard to understand.
- Writing unified logic that lives in a single executable can make scaling the application all but impossible.
- What’s needed is a way to keep the application’s logic unified, making it more understandable, while still letting the application scale.
- Achieving this is a primary goal of Windows Workflow Foundation (WF).
- By supporting logic created using workflows, WF provides a foundation for creating unified and scalable applications.
- Along with this, WF can also simplify coordinating parallel work, tracking a program’s execution, and more.
The Challenge: Writing Unified, Scalable Application Logic
- A simple way to write a program is to create a unified app that runs in a single process and single machine.
- The pseudo-code here shows the kinds of things that applications usually do:
- Maintain state (here is represented by a simple string).
- Get input from the outside world, such as by receiving a request from a client via a HTTP request or a SOAP message from another application.
- Send output to the outside world.
- Provide alternate paths through logic by using control flow statements.
- Do work by executing appropriate code at each point.
- In this unified approach, the application logic spends its entire life running on a thread inside a particular process on a single machine.
- This simple approach has several advantages. The logic can be implemented in a straightforward, unified way.
- This helps people who work with the code understand it, and it also makes the allowed order of events explicit.
- Another advantage of this approach is that working with the application’s state is easy.
- That state is held in the process’s memory, and since the process runs continuously until its work is done, the state is always available.
- When the application needs to wait for input it will typically just block and both the thread and the process it’s using will be held until the input arrives, however long that takes.
- A more scalable approach is to shut the application down when it’s waiting for input, then restart it when that input arrives.
- One common example of a technology that works this way is ASP.NET.
- A developer implements an ASP.NET application as a set of pages, each containing some part of the application’s logic.
- When a request arrives, the correct page is loaded, executed, then unloaded again.
- An application built in this style can use machine resources more efficiently than one created using the simpler approach shown earlier, and so it will scale better.
- Yet we’ve paid for this improved scalability with complexity.
- Because each chunk is loaded on demand, executed, then shut down, this state must be stored externally, such as in a database or another persistence store.
- Rather than just accessing ordinary variables, a developer now must do special things to acquire and save the application’s state.
- Another cost of this improved scalability is that the code no longer provides a unified view of the program’s overall logic.
- The chunk of code that handles the client’s second request might need to begin by checking that the first request has already been done.
- When you implement any kind of business process, understanding and correctly implementing the control flow across various chunks can be challenging.
Creating Unified Application Logic
- A workflow-based application created using WF does the same kinds of things as an ordinary application: maintains state, gets input from and sends output, provides control flow, and executes code that performs the application’s work.
- In a WF workflow, all of these things are done by activities.
- Every workflow has an outermost activity that contains all of the others.
- The outermost activity is called Sequence, and like an ordinary program, it can have variables that maintain its state.
- Because Sequence is a composite activity, it can also contain other activities.
- All of these activities correspond functionally to various parts of a typical program, but rather than using built-in language elements, each activity in a WF workflow is actually a class.
- Execution of the workflow is performed by the WF runtime, a component that knows how to run activities.
- It’s important to understand that the WF runtime doesn’t know anything at all about the activities it’s executing.
- This approach can help us create better code.
Providing Scalability
- To be scalable, a server application can’t be locked into a single process on a single machine.
- Yet explicitly breaking application logic into chunks breaks up a unified control flow.
- It also forces the programmer to work with state explicitly.
- What we’d really like is a way to have our logic automatically broken into chunks that can execute in different processes on different machines.
- One obvious advantage of this approach is that the workflow doesn’t hang around in memory blocking a thread and using up a process while it’s waiting for input.
- Another advantage is that a persisted workflow can potentially be re-loaded on a machine other than the one it was originally running on.
- Because of this, different parts of the workflow might end up running on different systems.
- The WF runtime doesn’t care how long the workflow has to wait for input.
- As long as the persistence store holds onto the workflow’s state, the workflow can be restarted.
Coordinating Parallel Work
- With WF, you can make coordinating parallel work easier.
- The WF BAL includes activities that correspond with familiar programming languages
- You can write workflows that behave much like ordinary programs.
- Parallel is a standard part of WF’s Base Activity Library, and it does exactly what its name suggests: executes the activities it contains in parallel.
Providing Automatic Tracking
- Since the WF runtime can see the boundaries between a workflow’s activities, it knows when each of those activities starts and ends.
- Given this, providing automatic tracking of the workflow’s execution is straightforward.
- As with other aspects of WF, this automatic logging requires essentially no work on the part of the developer. He can just indicate that tracking should happen, specifying the level he’s interested in, and WF takes care of the rest.
Kinds of Workflows