reMVC Storefront Part 19
Rob Conery has another MVC Storefront post, this time focusing on using Windows Workflow.
Those are my random impressions:
- You probably do want to test your work flow. In the same way you want to have an integration test for the system.
- The sequence work flow seems to be a very heavy weight approach to just orchestrating actions in the application.
- I wonder what the perf implications of creating a workflow here would be. My gut feeling is that this is not good, but I don't really have data for that.
- There is probably an issue here with the WF being run in async, I am not sure where it is getting its threads, but if it is from the thread pool, then it is consuming request handling threads, which can kill a site.
As an aside, here is the checkout workflow:
And here is how I would write this:
ValidateOrder() AuthorizePayment() order.Status = OrderStatus.Verified SaveOrder()
Much easier, I think :-) And even more flexible.
More posts in "re" series:
- (19 Jun 2024) Building a Database Engine in C# & .NET
- (05 Mar 2024) Technology & Friends - Oren Eini on the Corax Search Engine
- (15 Jan 2024) S06E09 - From Code Generation to Revolutionary RavenDB
- (02 Jan 2024) .NET Rocks Data Sharding with Oren Eini
- (01 Jan 2024) .NET Core podcast on RavenDB, performance and .NET
- (28 Aug 2023) RavenDB and High Performance with Oren Eini
- (17 Feb 2023) RavenDB Usage Patterns
- (12 Dec 2022) Software architecture with Oren Eini
- (17 Nov 2022) RavenDB in a Distributed Cloud Environment
- (25 Jul 2022) Build your own database at Cloud Lunch & Learn
- (15 Jul 2022) Non relational data modeling & Database engine internals
- (11 Apr 2022) Clean Architecture with RavenDB
- (14 Mar 2022) Database Security in a Hostile World
- (02 Mar 2022) RavenDB–a really boring database
Comments
I think this should use a DSL.
It is easy and cool using the designer in the beginning but after a while you see that is quite slow and cumbersome to use and specially when it gets a little longer then that.
does anyone know about scenario where WF approach would be more suitable than classical POJO approach? i can imagine asynchronous orchestrations but seems that people use it also in cases like you've just demonstrated. is the primary motivation to see "nice" diagram of flow ?
I'm glad to see I'm not the only one who thought this.
WF will always feel an overkill until your workflows start suspending, wait for external interaction, communicate, have more complex rule-based policies, etc. This is the tip of the iceberg of the technology.
The WF scheduler runs on a dedicated thread and the WF runtime dispatches on threads depending on where it is hosted (ASP.NET, WinForms, etc).
WF activities execute for a very limited time an I don't see them as a threat to choke the threadpool serving the ASP.NET requests.
Great MSDN article on WF perf: http://msdn.microsoft.com/en-us/library/aa973808.aspx
Regarding testing, you can easily test a workflow as an integral part of WF is Activity.GetService that can be thought as a simplified way of implementing IoC. Thus mocking services should be a breeze (even infrastructure services such as IWorkflowPersistenceService, etc).
Workflows are also declarative by nature, have great support for transaction management, are modifiable without recompilation and have low overhead for scenarios where you're not using advanced features of the technology.
It badly requires VERY GOOD understanding of the design motivations behind the technology. I recommend the Addison-Wesley book on WF by Shukla and Schmidt for just that (very good read).
WF is great when you have long-running processes and/or need tracking. The example shown looks like it would take a fraction of a second to execute, but what if AuthorizePayment was a manual process that might take a few hours or days? And then you have 100 of these running, and you want to know their status...which the WF tracking services will give you with little effort.
The problem with WF is that there aren't many good examples that wouldn't be trivial to implement in a few lines of code. It will be interesting to see if the Storefront example actually leverages some of the more advanced WF functionality.
One thing I'm learning (which I really should have learned by now) is to get more detailed when I show samples :). The one you show here Oren is really, really basic and I'm planning on building it out. You're correct, though, if this is all I had then I would put it in code. But for the people picking the site up, this is far from their end scenario.
Gabor,
A syncronnous request is going to take up a thread. If that thread is a pool thread, this means that you are starving ASP.Net.
Long running workflows are actually pretty easy to deal with, including persistence. External interaction isn't within the realm of the workflow, it is within the realm of the activities.
Rules are easy, just code them.
So far I am not buying into workflow either but I appreciate what Rob is doing.
I think Oren is right WF does use the threadpool according to Andrew http://blogs.msdn.com/pandrew/archive/2007/11/13/patterns-for-long-running-activities-in-windows-workflow-foundation.aspx
And from most of the comment here and over at Rob site then you won't be able to appreciate WF until you really scale up. So to put 2 and 2 together once I scale up I start to have to manage my own thread... not so simple to me. Threading is not hard, but it can be tricky to debug so that seem to dismiss the easy of use for WF. Plus from what I can see there is nothing else that WF bring on the table that can't be done via other means by a good design like Oren pointed out.
But I like I said I appreciate what Rob is doing and I would love to be proven wrong... :) I was skeptical at first when I heard about LINQ but it really blow me away...
IMO article like this reflects common problem with lots of MS technology samples: they try to demonstrate lot of their "enterprise" tech on a extremely dumbed down and really inappropriate scenario. Also, they tend to get their priorities horribly wrong (with the tech itself) - with WF last time I checked storing ruleset in external repository (like SQL database) required manual coding which is the most stupid thing I can imagine considering the target for this tech. It's like opposite to putting unit tests into enterprise version of visual studio.
Workflow Foundation allows you to modify almost every execution aspect through injectable services. In this case, you just need to replace the DefaultWorkflowSchedulerService with ManualWorkflowSchedulerService (both are scheduling services that come in the framework).
After that, you need to manually execute a workflow instance thus donating the current thread which in this case will be the current ASP.NET thread.
You can read more at this Scott's article:
http://www.odetocode.com/Articles/465.aspx
Workflow Foundation is very flexible
I agree, the workflow really didn't add much other than forcing the developer to encapsulate functionality.. or rather that you should be writing functionality in a non-monolithic sense, the best way to think of this is that a single method should have a single 'task' and any subtasks should be more methods.. this keeps code clean, reusable, easier to transaction - tons of things..
Using workflow, while interesting to someone who hasn't used WF, what really was interesting to me was the state machine, I wasn't aware of WF having state machine functionality.. but WF seems to be 'heavy' enough that an entire application may well be the focus for its work, vs a component in an application..
Could be well off the mark with workflow however, but given that its trying to manage its own threads, that seems pretty heavy - and as others have stated, running wf inside an asp.net app domain is a bit scary..
As well as this, given that the wf was there to process data in an offline sense - why should it be tied into the lifetime of the web app?
To me, the WF could/would be another process sat watching.. I dunno - a sql database, and processing new orders that are added.. (if you really want seperation between processing, which seems logical given that this could process orders then that don't emit from the website).
Ayende,
You should read the book from Kent Beck (implementation patterns)
ValidateOrder() //HIGH
AuthorizePayment() //HIGH
order.Status = OrderStatus.Verified //LOW --> SetOrderStatus()
SaveOrder() //HIGH
Then you would see that your WF code has high level methods mixed with low level methods. Thus not improving code readability (and code is meant to be read not written !!)
of course nothing to do with the actual intent of the post (sorry about that), but just an observation !
Comment preview