15

I'm a beginner with WF, but I've read a book and done a lot of googling. I want to write an inventory management service. The inventory is made up of individual items which have a state:

  1. Spare
  2. Installed
  3. In-Repair

Items may spend months in each state, and there are thousands of items.

The question is, do I create a state machine workflow for all the different states? Or do I create workflows for transitioning between states?

If I understand correctly, if I create a single state machine workflow, then there will always be a workflow running for every item. This means thousands of ever-running workflows. Also, I need to be able to display a snapshot of the status of each item, so that means I have to somehow query all the workflows for the state they are currently in, or otherwise persist to a database after each state transition.

However, a state-machine workflow logically sounds like the right thing to do, hence my dilemma.

Please help me if you can :-)

Thanks!

Update:

Assume I have more states than the above 3, and that not all state transitions are possible.

Bounty Winner: Maurice - Thanks to everyone else for really helping me understand more about workflows, the MS workflow foundation, and other more lightweight alternatives. Unfortunately, there can only be one bounty winner, and Maurice's answer along with its comments helped me the most.

Aviad P.
  • 32,036
  • 14
  • 103
  • 124
  • 1
    I'm no workflow wizard, but as an architect I would seriously question your approach to model inventory item states with a workflow engine. Or maybe I miss something. What do you use the workflows for? – TToni Dec 29 '09 at 22:44
  • The 'meat' of the workflows lies in the transition between states, where I need to validate my business logic. For example, when transitioning between *Spare* and *Installed* I need to make sure that the installation location is vacant first, then I have to change state, and then I have to notify logistics about the installation, etc. – Aviad P. Dec 29 '09 at 22:50
  • OK, so you need to execute some business logic when an item changes state. But I still don't see why you would use WF to do this. I assume you store the current state of each item in some database anyway. If you don't and there are other good reasons to use WF, then having one WF instance for each item looks like the better alternative to me. But if the state transitions of the WF only reflect the item state transitions, then you just end up storing the item state in a complicated way (as persistent WF instances instead of some database column). – TToni Dec 29 '09 at 23:15
  • What you're saying makes sense, but then can you think of anything that would make this scenario better suited for a state-machine workflow? - Also, using a workflow (state machine or otherwise) is a good practice in and of itself, it makes the flow of execution much more clear. By not using a state machine workflow, some of the process is obscured in code. That's part of my dilemma. --- Good night TToni :-) – Aviad P. Dec 29 '09 at 23:21
  • I still don't feel that WF instances are the right tool to capture your inventory item states. If you have non-trivial logic that you want to capture in a WF for item state transitions, that's fine, but why not use a different WF for each transition, instead of one big WF that includes the inventory item states? You can still use a process model diagram to explain your overall logic, but you don't have to capture everything in a WF model. If someone runs into problems like yours then it's 99/100 times an indicator of using a component in a way it's not meant for. – TToni Dec 30 '09 at 07:05
  • Explain that last sentence again: 'if someone runs into...' what do you mean? Isn't this dilemma common? Can you give an example of when it's more correct to use a (ongoing) state-machine workflow? Also, you might want to collect all of our thoughts and conclusions into an actual answer post... – Aviad P. Dec 30 '09 at 09:18

9 Answers9

22

A state machine is a very powerful technique to implement, although I would recommend that you consider a framework called StateLess by Nicholas Blumhardt (Autofaq creator), as it is an amazingly simple implementation of a state machine that avoids the unnecessary complexity of Windows Workflow. His approach avoids the issue of long running workflows being held by a runtime engine, as the state is defined by a simple variable such as a string or int.

Here is a sample state machine:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

phoneCall.Configure(State.OffHook)
    .Permit(Trigger.CallDialed, State.Ringing);

phoneCall.Configure(State.Ringing)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.CallConnected, State.Connected);

phoneCall.Configure(State.Connected)
    .OnEntry(() => StartCallTimer())
    .OnExit(() => StopCallTimer())
    .Permit(Trigger.LeftMessage, State.OffHook)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.PlacedOnHold, State.OnHold);

// ...

phoneCall.Fire(Trigger.CallDialled);
Assert.AreEqual(State.Ringing, phoneCall.State);

Your state can be an integer which will allow you to feed it the current state from a database. This can be set on the constructor of the state machine as follows:

var stateMachine = new StateMachine<State, Trigger>(
    () => myState.Value,
    s => myState.Value = s);

You can implement this in just one assembly, compared to the multiple projects you need to run Windows Workflow. Maintenance is extremely low, their is no "designer" that generates code for your, etc. Again, it is simple, and there lies the beauty.

Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169
David Robbins
  • 9,996
  • 7
  • 51
  • 82
9

Not sure if a workflow is what you are looking for in the first place.

A workflow is some kind of business process that takes place. This implies a beginning and an end to the process. Your description sounds more like you are tracking an inventory of sorts with items that stay in the inventory.

A workflow sound more appropriate when an item changes state. For example when an item is installed and breaks down and needs to be fixed you would start a workflow to get the part replaced by a a working one, send the broken part to be fixed and in the end have it back at the warehouse as a fixed spare. The workflow would describe this process and start with the report of an item being broken and end with the item being either repaired or discarded and replaced.

This last workflow could very well be a state worklfow as the item goes through various stages like:

  • Broken and installed
  • Broken and replaced
  • In the shop for repair
  • Repaired
  • etc
Maurice
  • 27,582
  • 5
  • 49
  • 62
  • A workflow doesn't have to have an end. That's the theory of course, for example, even if items may end up in the recycle bin, they can still be restored, there's no final state for the item, barring total disintegration. - Also, I am, of course, using workflows for the transitions between states, that's a given, and would be regardless of whether I also include a state-machine or not. – Aviad P. Dec 30 '09 at 12:31
  • I think the potential problem with endless workflows is that you have to update your objects 'in place' if you want to change business logic. If you change your workflow, maybe that would affect things like your database schema for persisting the workflow, which might turn out to be painful. Maurice's answer sounds like a good way of trying to avoid that issue. – Tim Lovell-Smith Dec 30 '09 at 16:45
  • +1. Workflow foundation is simply not the appropriate technology for problem defined in the question. @Aviad: Yes "theoritically" workflows do not need to end. However WF has more specific goals than a theoritical workflow. It is specifically aimed at Business processes that do come to a logical end. It is designed to model in-progress __tasks__. It is certainly not designed to handle thousands of very long running workflows. – AnthonyWJones Dec 30 '09 at 21:38
  • @Aviad: You are right that a workflow never needs to end. No program has to end but most do and for a good reason as there is very little that needs to go on for eternity. Creating an ever running workflow is easy and with persistence might not even cost much resources. However programs tend to fail so you need something else that makes sure no workflow disappear unnoticed. That is yet another program. Keeping the data in a database and starting a workflow when something happens is much more appropriate and safe. – Maurice Dec 31 '09 at 14:35
2

Given Your additions (more than 3 states, not all transitions are allowed), I would do the following:

  1. Store each item's state in the item itself.
    This can be achieved very easily: Add a member to a class or a column to a table etc., as others already mentioned in their posts/comments.
  2. Use one state machine (this can be anything from an instance of a class to a table with legal transitions), that holds your business logic, that is, the allowed transitions between states and the knowledge about what additional actions to perform, when an item changes its state.

All you need to do then is to transform Your items using the state machine, whenever an extern event occurs, that forces/implies just that.

Dave O.
  • 2,231
  • 3
  • 21
  • 25
  • I agree. You can use interfaces and dependency injection techniques to make the model flexible as well. – Brandon Montgomery Dec 30 '09 at 04:33
  • Does this refer to the actual .NET workflow foundation? Or are you talking about workflows in the english dictionary meaning of the word? I'm interested strictly in the former, while it looks like it is the latter... – Aviad P. Dec 30 '09 at 05:23
  • Oh I'm sorry Aviad. You didn't explicitly mention .NET workflow foundation, so I assumed You were asking for general ways to realize Your project. – Dave O. Dec 30 '09 at 13:47
2

ok. let's see if I can help you. Let's start with the design:

it makes sense to design a state machine AND a Workflow. Both are just different views on your problem and shed some light from a different perspective on it. In fact, it often happens that a developer which is new to workflows designs a state machine instead of a workflow process. The workflow process view mainly switches the roles of the boxes and transitions in the diagram: a box is an activity which can change a state - on a transition, a workitem can get into a new state (ok, thats not scientifically correct, but it might help :-)

For me it seems that the state machine aspect is more important. So implement your software as a state machine.

And yes - you should make all items persistent in a database. That's how you also keep very long running workflows running - they live in the database until they get reactivated by any activity. That's how all off the shelve Business Process Management Systems (BPMS) do it. Those workflows are NOT kept in memory.

Keeping everything in the database will make it easy to create reports.

As other already have mentioned, create a new colum with the state information or even create a new table with meta data: state, maybe a log when the state has changed, who changed the state, infos about upcoming events (a part has been ordered but not delivered - after how many days should someone check with the supplier if the delivery has been lost?). This will give you the opportunity to add meta data as needed without affecting your parts database.

Hope that Helps!

rdmueller
  • 10,742
  • 10
  • 69
  • 126
  • I want to get specific regarding the use of .NET Workflow Foundation. Are you recommending that I use a state machine workflow along, of course, with state transition workflows, but that I use my own persistence for the items (which include their state)? - Also, I never intended for the workflows to remain in memory, of course they would be persisted using a workflow persistence service, but the form in which they are persisted by the SqlPersistenceService is opaque to me, I can't query it or do anything except reload the workflow. They would however never reach a final state - is what I meant – Aviad P. Dec 30 '09 at 12:29
  • I haven't worked with the .NET Workflow Foundation yet, and I gues I never will. I am turning my back to another Workflow solution because too much of the stuff is opaque to me. Often you see the solution, but the framework will not let you implement it. But that's another topic. When you work with a framework, try to stick to it. Implement your process / workflow / state machine the way the framework suggests. everything else will cause problems. Maybe the workflow foundation isn't the right frame work for your app if it causes too many problems? – rdmueller Dec 30 '09 at 13:09
  • btw: a workflow which never reaches a final state shouldn't be a problem for a workflow engine. I guess the limit is more the number of active workflows which seems to be quite static in your case... – rdmueller Dec 30 '09 at 13:10
1

As discussed in the comments to the original post I have some issues with using WF for this particular problem at all.

The sentence "Items may spend months in each state, and there are thousands of items" is the trigger for this: I believe that workflows (modeled with WF) should be shorter lived. While there is no hard rule as to how long a WF instance can or should live, several months or maybe even years triggers kind of an "out-of-bounds" exception with me, especially when this would be a very common state of affairs for thousands of items :-)

The reasons for using WF in your comments are sound, but don't address this particular point. So I would advise you to use shorter lived, specialized WF models for the things that happen between inventory item states, but don't capture the item state itself in a WF state. Long lived, seldom changed states are more suited to a database engine, where people expect them to be and where they are easily reported upon.

TToni
  • 9,145
  • 1
  • 28
  • 42
  • Thanks for all your input TToni, I am still not convinced that there's no place for perpetual (state-machine) workflows. The theory talks about that, and the implementation definitely supports that. However I am finding it hard to ignore all the hindrances a state-machine workflow would incur on my application... The dilemma is still in effect :-) – Aviad P. Dec 30 '09 at 12:42
  • Well that's what I talked about. If you want to use some kind of tool but can't find a straightforward way to make it work for you, you probably use the wrong tool. Or you have a very difficult or innovative problem at hand (which does not seem to be the case here). Good luck anyway. I'll be offline for a while now. – TToni Dec 30 '09 at 15:25
0

Even though the state-machine pattern is technically the correct option, there's also an option to create a sequential workflow with one giant loop. In some cases, it actually works better and is more understandable.

Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166
  • 1
    Doesn't address my dilemma - do I create an ever-running workflow (read - a state machine workflow) for each item, or do I only use the sequential workflows for transitioning between states. – Aviad P. Dec 27 '09 at 20:47
0

You have three distinct states and as far as I can see, all transitions are allowed. Given that, I would not bother about a state-machine in the sense of a piece of code that checks the allowed transitions and does the moving forward.

State machines make sense when the states drive the business or when there needs to be a trusted single piece of code that is the sole actor in charge of "validated transitioning".

Put more simply, you just need the entities with a given state at any point in time...

raoulsson
  • 14,978
  • 11
  • 44
  • 68
0

Aviad, I agree with your comment that the workflow should be between states. The states of the parts being inventoried sounds like a status/property of the item. That status can be stored in nearly any manner (e.g. database, file...) because the movement of the item between states would live in the business logic layer.

Sounds like a fun project, good luck.

0

I think we need to understand couple of things here.

State Machines - Will focus on representing a particular state your entity is in.

WorkFlow - Will define the processes you are following for moving your entity from initial state to final state.

In your case as your overall process is revolving around a single entity and its current status at any given point of time is singleton, I would recommend to go for a state machine.

Recommendation: Apache Commons SCXML provides a lightweight, embeddable state machine engine which can easily be configured and customized at runtime within your application.

Key point here is you have to define your scxml in such a way that between the state transitions of your entity - You can specify the workflows you want to perform using 'actions' or 'listeners'.

SAMPLE PROGROM: https://www.javacodegeeks.com/2012/06/apache-commons-scxml-finite-state.html

MORE ABOUT Commons SCXML 2.0 https://events.linuxfoundation.org/sites/events/files/slides/ApacheConUS2014%20-%20Apache%20Commons%20SCXML%202.0.pdf