Now that Microsoft has revamped their workflow framework in Windows Workflow Foundation 4, what are your thoughts and experiences with this new framework?
I have been working with WF4 for a few months now, and I have run into a few pitfalls:
There's no way to enforce an interface with Workflow Services (Xamlx).
When an error occurs in the workflow, whether it is with communication, correlation, persistence, or some unhandled exception in the workflow, it's almost impossible to tell what went wrong because the trace logs tell you nothing relevant. For example, I had an Entity Framework object as a workflow variable and the workflow persistence had some trouble serializing it. Unfortunately, non of the errors in the trace files indicated that this was the problem. I went through many hours of trial and error before I figured out what went wrong.
Some of the provided activities are insufficient. For example, I had to extend the Send activity to support dynamic endpoints. Unfortunately, I wasn't able to make it completely dynamic, for example, the interface name cannot be dynamic.
If a workflow gets too big, the designer becomes very slow. One workflow that's over 100KB in size took more than a minute to load! And forget about debugging a workflow of this size.
No persistence provider for Oracle.
Despite the pitfalls, I'm very impressed with the persistence capabilities to the database, the ease of snapping activities together in the designer, and the ease of setting up WCF services as workflow services.
I'm curious about the experiences of the other developers using Workflow Foundation 4.
Edit:
I was able to solve the problem of the extremely slow designer for large workflows. It turned out that there were unresolvable Imports, which apparently causes the designer a lot of stress.
I posted on the MSDN forums about this issue.
Update
There are a slew of problems that we are facing with AppFabric, now that we're running in production. It is clear to me that AppFabric Workflow Services, as of now, are not ready for use. I would stay away from this until new versions are released.
I think you did a pretty good summary of the WF4 issues.
My main pain point is the inability to change the definition of in process workflows. That is being fixed in the next version though but for now a big problem.
I also had difficulties with exceptions in workflows - mostly determining why they occurred, the source, and a description or message. I got better at this as I gained more experience, and if I began another workflow project I'd be able to debug it far more efficiently. It's just a different paradigm and so can't be approached the same way as straight code.
Another issue I had with WF 4.0 was unit testing with WorkflowInvoker; the specifics escape me but mocking dependencies and parent/child workflows was a real headache.
Generally I really like WF 4.0, a massive improvement over 3.5. Running in debug mode can be very slow, debugging in the designer is more trouble than it's worth, but the framework is great and very usable.
Related
My team is developing an iOS framework for the clients to use, and we came upon a bottleneck when we wanted to have some sort of crash reporting tool(such as Crashlytics, KSCrash, etc.) in our framework so we can track down the crashes when clients are using our framework in their app.
However, the problem was that these 3rd party crash reporting tools don't seem to work if both (framework and client) are using the same crash reporting tool. For example, if our framework and client app both depend on Crashlytics to report crashes, it wouldn't work because of restricted API. Most other open source projects almost all the time uses sharedInstance to initialize the class. So, this wouldn't work either.
My question is... I'm sure there are companies and software out there that use some sort of crash reporting tools to analyze crashes on their own frameworks that they distributed to many clients. How is this done? Any insights?
I'm a former maintainer of the Crashlytics SDKs for Apple platforms. I've been asked this a number of times, by some highly popular framework vendors in the past. And, I've devoted a significant amount of work into these areas - reporting tool interoperability and non-host app reporting.
I'd like to get into a little more detail as to why this is so difficult.
Problem 1: Crashes are inherently per-process
The problem you've noticed so far is related to the reporting frameworks' APIs, but the issues go way deeper. A crash brings down the entire process. The facilities that exist on iOS (macOS, tvOS) cannot be applied on a per-library basis. (I believe some can be per-thread, but I'm not sure that actually buys you anything.)
This is the core reason why interoperability, even with Apple's own ReportCrash, is so challenging. In-process reporting tools setup their machinery, and then expect their setup to remain unchanged when a crash actually occurs. Two copies of this machinery (ie, two Crashlytics) doesn't make sense. There can only be one, because the resources being used only exist on a per-process basis.
Often, a reporting tool needs to make trade-offs between the best possible reporting, and the best possible interoperability. On example, if I remember correctly, is that if you use both Crashlytics and KSCrash in the same process, Crashlytics' ability to correctly capture information about C++ exceptions is compromised.
Problem 2: Who owns the crash?
Ignoring problem 1, how should the reporter know that a crash is a library vs the app? This is broad topic, that basically gets down to the core issue of crash responsibility. A crash is an effect, but most developers don't immediately think of crashes this way. When you want to fix a crash, you need a cause. Determining that a library is the cause is not easy. Before you think "shouldn't it just give me the crashes with my library's frames in it?", imagine that was how it worked for UIKit or Foundation.
There are many ways to approach this issue. However, without digressing here too much, I believe a crash is always owned by a host application, but could also be interesting to third-parties. This brings up a whole other host of issues, including authenticating library owners and dealing with the privacy/security implications for the host app. It's a whole thing.
Regardless of how you approach this, I think the solution can only be done server-side, with the reporting service. They could, in theory, grab the report and do this analysis. Crashlytics' Insights system is a step in this direction. However, it currently does not offer a library vendor the ability to see these reports. Its focus is more on connecting the crash (an effect) with a well-known cause (or class of causes).
Summary
Trying to make your library as stable as possible is an excellent goal. Unfortunately, I just don't think it can be done with dedicated in-process reporting.
What you should actually do is help your client developers better understand what your library is doing. So, when it does crash, then can debug more easily and report it to you.
Name all of your queues/threads
Include some kind of logging facility
Be aggressive about checking for valid parameters/input
make errors you pass back from your APIs as descriptive and comprehensive as you can
Don't ever Assert in production (I feel the opposite about this for host applications)
Never throw ObjC and/or C++ exceptions
Never, ever #catch/catch in your code
check out the NSProcessInfo APIs, which can help better expose what your library is doing during debugging
I hope this is helpful, even though it doesn't really get you where you wanted.
New to NServiceBus (4.7.5) and just implemented an NSB host.exe hosted service (implementing IWantToRunWhenBusStartsAndStops) that detects changes to database tables and notifies subscribing web apps by publishing events, e.g. "CustomerDataWasUpdatedEvent". In the future we will perform the actual update through messagehandlers receiving commands obviously, but at the moment this publishing service just polls the database etc.
It all works well, however, approaching production, I noticed that David Boike, in his latest edition of "Learning NServiceBus", states that classes implementing
IWantToRunWhenBusStartsAndStops are really mostly for development and rarely used in production. I set up my database change detection in the Start method and it works nicely, does anyone know why this is discouraged?
Here is the comment in the actual book:
https://books.google.se/books?id=rvpzBgAAQBAJ&pg=PA110&lpg=PA110&dq=nservicebus+iwanttorunwhenbusstartsandstops+in+production+david+boike&source=bl&ots=U6sNII0nm3&sig=qIXffOVFhcy-_3qDnSExRpwRlD4&hl=sv&sa=X&ei=lHWRVc2_BKrWywPB65fIBw&ved=0CBsQ6AEwAA#v=onepage&q=nservicebus%20iwanttorunwhenbusstartsandstops%20in%20production%20david%20boike&f=false
The actual quote is:
...it isn't common to have widespread use of in a production system.
Uncommon is not the same thing as discouraged.
That said I do think there is intent here by the author to highlight the fact that further up the page they assert that this is not a good place to be doing lots of coding, as an unhandled exception can cause the whole process to fail.
The author actually does go on to mention a possible use case for when you may want to load a resource(s) to do work within the handler.
Ok, maybe it's just this scenario we have that is a bit uncommon
Agreed - there is nothing fundamentally wrong with your approach. I recently did the same thing as you for wiring up SqlDependency to listen for database events and then publish a message as a result. In these scenarios there is literally nothing else you can do other than to use IWantToRunAtStatup.
Also, David himself often trawls the nservicebus tag, maybe he'll provide a more definitive answer than mine.
I'll copy the answer I gave in the Particular Software Google Group...
I'll quote myself directly here:
An implementation of IWantToRunWhenBusStartsAndStops is a great place to create a quick interface in order to test messages during debugging by allowing you to send messages based on the console input. Apart from this, it isn't common to have widespread use of them in a production system. One possible production use case will be to provision a resource needed by the endpoint at startup and then tear it down when the endpoint stops.
I think if I could add a little bit of emphasis it would be to "widespread use". I'm not trying to say you won't/can't have an IWantToRunWhenBusStartsAndStops in production code or that avoiding them is a best practice. I am trying to say that having a ton of them is probably a code smell.
Above that paragraph in the book, I warn about IWantToRunWhenBusStartsAndStops not having any ambient transactions or try/catch stuff going on. THAT is really the key part. If you end up throwing an exception in an IWantToRunWhenBusStartsAndStops, tyou can run into big problems. If you use something like a .NET Timer and then throw an exception, you can crash your process!
Let me tell you how I screwed up on this in my first-ever NServiceBus system. The system (still in use today, from what I hear) is responsible for ingesting more than 3000 RSS feeds (probably a lot more than that now) into a CMS. So processing each feed, breaking it up into items, resizing images, encoding attached video for mobile ... all those things were handled in NServiceBus message handlers, which was scaled out to multiple servers, and that was all fantastic.
The problem was the scheduler. I implemented that as an IWantToRunWhenBusStartsAndStops (well, actually IWantToRunAtStartup at that time) and it quickly turned into a mess. I kept the whole table worth of feed information in memory so that I could calculate when to fire off the next ProcessFeed command. I was using the .NET Timer class, and IIRC, I eventually had to use threading primitives like ManualResetEvent in order to coordinate the activity. And because I was using .NET Timer, if the scheduler threw an exception, that endpoint failed and had to restart. Lots of weird edge cases and it was always a quagmire of bugs. Plus, this was now a singleton "commander app" so while the feed/item processors could be scaled out, the scheduler could not.
As I got more experienced with NServiceBus, I realized that each feed should have been a saga, starting from a FeedCreated event, controlled through PauseProcessing and ResumeProcessing commands, using timeouts to control the next processing time, and finally (perhaps) ended via a FeedRemoved event. This would have been MUCH more straightforward and everything would have executed inside transactionally-controlled message handlers.
That experience led me to be a little bit distrustful/skeptical of IWantToRunWhenBusStartsAndStops. Not saying it's bad, just something to be aware of. Always be prepared to consider if what you're trying to do couldn't be better accomplished in another way.
I'm currently trying to find the best message queue solution for an appharbor application. Most of the ones of looked at assume you have a windows environment with MSMQ and DTC installed, which I don't believe the appharbor environment provides.
I would like something that works well with ravendb, as that is the database we are using. Something who's only dependence is on raven would be ideal, especially if it integrates with our existing unit of work. Ie, when save changes is called in our controller action the messages are saved in the same transaction.
It would also need a host that works in a console application for background processing.
Ideally I would like something that "just works" in a development environment also. With raven, for example, we use the embedded mode while developing and I would like something that doesn't require installation.
I've looked at nServicebus, which seems to fail these conditions because it needs a transport (msmq, sql, etc) and much of the documentation is out of date.
I also looked at rhino service bus but there is a distinct lack of documentation and community. I'm also not sure if it can depend entirely on ravendb.
The others I looked at all seemed quite heavyweight and required installation and configuration to run in a development environment.
Edit: the other option, is to implement our own.
First of all, congratulations on being the 1000th NServiceBus question on StackOverflow!
Second, if you were to use SQL for persisting your business data, then you could run NServiceBus on top of that same SQL where all the messages go through tables (instead of queues) and then you wouldn't need the DTC.
Third, if you did want to go with RavenDB as your transport for NServiceBus, you would have to implement the ISendMessages and IReceiveMessages interfaces on top of it, but I believe that somebody in the community has already started working on that, so possibly you could join forces with them.
Finally, I wouldn't recommend writing your own ESB these days - not when there are so many good choices already out there. You mentioned the issues of community and documentation - those tend to be handled the worst when writing your own infrastructure.
I'm trying to figure out how to profile a WCF service so I can identify any bottlenecks.
I have found a bit of information on line, but nothing that assumes no prior knowlege which is where I'm at.
What are recomended FREE tools?
- visual studio tools
- clrprofiler
Here is information I found using vsperfcmd.exe to profile wcf service and according to this it is very simple, but I need to fill in the gaps on where to start. My assumptions are to copy VsPerfCLREnv and VsPerfCmd to the server that hosts my wcf service and perform some configuraiton steps that I'm not quite sure on. I'm also not quite sure how I would be able to see the call stack to evaluate the performance of each call.
clrprofiler seems a bit simpler. I assume I would copy clrprofiler.exe to the server, File->Profile Service and add the name and start/stop commands. (is this a friendly name or filename or the service display name?) I assume I would then run my tests against the service and I could see the call stack in clrprofiler. Does that sound correct?
[edit]
I'm not so interested in testing the network since this is on a test server, and this is a large wcf project with multiple devs on it and I am unable to make changes to the project for the sole purpose of monitoring the performance. I want to focus on the performance of the actual methods within it.
Any assistance on getting started is greatly appreciated.
For WCF it is not enough to profile your code only as bunch of things happen on the channel stack (security, deserialization, formatting etc). A good way to visualise that is by using WCF Tracing at verbose level and then using the service trace viewer to see how long it is taking at each step of message processing. Read here on how to configure and use WCF tracing. This is the single most thing that has hepled me with diagnosing WCF issues.
Of course all other code profiling, DB profiling etc. are valid approach as well. You may even use a tool like SoapUI to test your network communication and client side performance overhead for a more end-to-end benchmark.
some things I've learned that someone might find helpful:
you cannot remote profile a service, even over your local network. The profiler must be running on the same machine as the service. (This actually took me quite a while to figure out. Maybe obvious to you, but it was never spelled out so I kept trying to do it)
Visual Studio didn't work for me to profile my WCF service. I was able to get a bit of help from the VS profiler team, but never came out of it with a working solution.
VS was slow to connect and disconnect the profiler and often instrumented my binaries and left them in a corrupted state.
.net binaries do not need to be instrumented since they contain the metadata of the methods which is odd that visual studio kept hosing my binaries trying to instrument them.
I also tried the VS standalone profiler but this is very complex to use and requires reboots of my server.
I ended up getting an internal profiler to work (after getting a private build from the team) so I'm not sure how many profilers out there are designed to work with a WCF service.
I actually set the profiler to watch the WAS service and then added my additional binaries to the profiler.
process explorer is useful when troubleshooting if the profiler is connected or not. Use it to look at inetinfo.exe environment
Can you run it under a debugger?
Can you stand a simple, old-fashioned, method that just works? Here's one.
In addition to Mike's comments, you can use the built-in WCF performance counters to see a number of performance-related metrics and you can also see call times on a WCF trace. Once you know which operations are 'slow' it's usually easier to add some custom timing/logging code to those operations than using a general purpose profiler for something like this. This coming from someone who used to work on commercial profilers.
Tools you should look into: svctracelogviewer (and turn on tracing in both your service and clients). SoapUI for simulating load (and do analysis) and Fiddler, an excellent HTTP sniffer/diagnostics tool.
I work for a large state government agency that is a tad behind the times. Our skill sets are outdated and budgetary freezes prevent any training or hiring of new employees/consultants (firing people is also impossible). Designing business objects, implementing design patterns, establishing code libraries and services, unit testing, source control, etc. are all things that you will not find being done here. We are as much of a 0 on the Joel Test as you can possibly get. The good news is that we can only go up from here!
We develop desktop CRUD applications (in C++, C#, or Java) that hit the Oracle database directly through an ODBC connection. We basically have GUI's littered with SQL statements and patchwork code. We have been told to move towards a service-oriented n-tier architecture to prevent direct access to the database and remove the Oracle Client need on user machines.
Is WCF the path we should be headed down? We've done a few of the n-tier application walkthroughs (like this one) and they seem easy to implement, but we just don't know enough to understand if we are even considering the right technologies. Utilizing the .NET generated typed DataSets seems like a nice stopgap to save us month/years of work (as opposed to creating new business objects from the ground up for numerous projects). Is this canned approach viable for a first step?
I recently started using WCF services for my Data Layer in some web applications and I must say, it's frustrating at the beginning (the first week or so), but it is totally worth it once the code is deployed.
You should first try it out with a small existing app, or maybe a proof of concept to make sure it will fit your needs.
From the description of the environment you are in, I'm sure you'll realize the benefit almost immediately.
The last company I worked for chose WCF for almost the exact reason you describe above. There is lots of good documentation and books for WCF, its relatively easy to get working, and WCF supports a lot of configuration options.
There can be some headaches when you start trying to bend WCF to work in a way not specifically designed out of the box. These are generally configuration issues. But sites like this or IDesign can help you through those.
First of all, I would definitely not (sorry for the emphasis) worry about the time you'll save using typed DataSet's versus creating your own business objects. That is usually not where you will spend most of your development time. I prefer using business objects myself.
In you're situation I would want to implement a proof-of-concept first. One that addresses all issues you may encounter. This proof-of-concept should implement an entire use case, starting on the client, retrieving data from the database and returning it to the client. You should feel confident about your implementation before continuing.
Then about choice of technology. WCF is definitely a good choice for communication between your client applications and the service layer. I suppose that both your clients as well as your service layer will become C# applications? That makes things a lot easier since interoperability between different platforms (Java/C# for example) is still not trivial although it should work in most cases.
Take a look at Entity Framework (as there are a couple Oracle providers available for it already) in conjunction with .NET 3.5 SP1 which enables built-in WCF serialization of your EF generated classes.
Here is a good blog to get started: http://blogs.msdn.com/dsimmons
CSLA might be a good fit for your N-Tier desktop apps. It supports WCF, has a large dev community, and is well documented. It is very object oriented.