I recently joined a project where Workflow Foundation 4.0 is being used to model business processes.
We have a designer tool so that consultants for clients can customise the workflow definitions. We also persist the workflow instance along with the definition. The workflows can be long running (e.g. months or potentially years).
My question is how do we manage backward compatibility for each release given we don't necessarily know what customisations have been made and what legacy workflows are still in flight? We are loading from XAML but even seemingly minor changes to workflow definitions prevent them from loading. Migration scripts was my initial thought but it seems non-trivial given the complexity of WF workflows.
First off, XOML is 3.0; WF4 uses straight up XAML.
There are two options for doing this. It depends on whether you need to upgrade a long-running workflow in process, or if you want to update the workflow and use it for all new instances, while keeping current instances running on the previous version. Lets call these two options the upgrade and the multiversion strategies.
Re multiversion:
I'm doing this currently. Essentially, you must isolate every different version of the same workflow within an AppDomain. Deserializing from xaml or creating a new instance of a type is the same thing--they both result in an assembly being loaded into the current AppDomain. If v1 of the workflow is defined in assembly A.1, and v2 of the workflow is defined in assembly A.2, you can experience binding issues if you aren't careful. Isolating each version within its own AppDomain helps reduce the chance of this happening.
Re upgrade:
This currently isn't being supported, but there are plans on including this in a (near) future release. Ron Jacobs gave a presentation at PDC10 last October detailing WF4 futures. Three things (I can remember) were mentioned in the presentation--Metadata errors breaking the build, the state machine, and providing an upgrade path for workflows during execution. I can tell you that the state machine was released in the recent Platform Update, and I've been told the metadata-error-breaks-the-build feature is coming soon as well. I'd assume that the upgrade path feature will be coming soon as well.
I've done some research on this.
WF4 Workflow Versioning Spike
WF4 Versioning Spike: Planning for Change
Distributed System Versioning Myth #1
Related
we are a team of 5 people working with microstrategy. We share every role, but we have no worklfow.
Everybody may build or change attributes and change the schema. This leads often to reports not working. Furthermore, there is no "good" documentation. We tried to establish a documentation with sharepoint, but there we also had no workflow.
Originally, we had an old project where for every report all the attributes where constructed newly. So we did not reuse any existing schema object.
Hence, we started a new project. We realized that due to lack of understanding and lack of workflow we make and made a lot of mistakes. We feel that we understand things better slowly (parent child), but the workflow is still horrible.
We have a development project and a lice project, but with the way we are working now, we have a lot of problems. Particularly, the missing version control system is killing us. We perform changes and forget what we did. Hence, we have to use backups, destroying useful work on a given day
So what are best practices to:
* deploy new attributes, facts and reports
* ensure that old reports work after constructing new attributes and facts
* improve documentation
* attributes defined on fact tables and parent-child relationships
Any help is appreciated
MicroStrategy development in a team environment, deploying from development to live, can be very challenging. As you rightly point out, the lack of version control, and unknown interdependencies between objects can cause untold problems. There's no one right answer to this question, but I would suggest the following:
Use all the tools provided by MicroStrategy. When you're deploying from one project to another, don't just drag and drop in Object Manager, create a package. When you deploy that package, make sure you choose to create an undo package, so you can rollback changes if you encounter any problems.
On that note, try to catch these problems in advance. Running Integrity Manager before and after a deployment, even if it's just to generate SQL for the reports, will point out if you've broken anything. On that note:
Create a third environment/project. Call this test/release control, whatever you prefer. Here you can test packages created in Object Manager, to ensure that they have the desired effect, and don't break anything. In effect, this is a dry run for your deployment to live. This environment should be regularly refreshed from live (via project duplication), to make sure it doesn't get in an unexpected state (as the result of a broken Object Manager package import for example).
Over and above that, I can only offer organisational advice. It's not uncommon for one person to take responsibility for schema objects (i.e. facts, attributes, transformations) so that developers don't undo each other's changes. If you have a large project, these objects could be split into functional areas, and individuals assigned.
Documentation is always tricky, but I like to put as much as possible into the object descriptions. This has the advantage of being visible in the Web interface (via tooltips), and included in the automated project documentation, should you choose to generate that. There is obviously the change log functionality for each object, but in my experience, those logs are soon not completed by developers, as saving happens too frequently. Still, if you can get people to populate that, you'd have a head start on understanding the change in your project.
To summarise:
Use Object Manager packages to deploy changes
Test changes with Integrity Manager, to catch any issues as early as possible
Use a release control project/environment, so you're not catching issues in your production environment
Assign responsibility for schema objects to a specific person or persons where possible.
This is not a "why should I use version control" question :-)
I have always used version control from the first line of code of every project I've written so far. However yesterday I came up with a question (maybe a stupid one) to which I find no answer: when should version control really start during the software development process? Should it start from the first line of code, as I've been doing all of my life, or should it start when you really have an operational version of your code? Put in other words: should version control be used before the first version of your software? (I mean version control, not source backup, of course!).
Pre-development you don't need version control; but what you do need is some form of collaboration mechanism to keep track of changes to the specifications and documentation.
Some teams deploy version control at this stage. Personally I don't find the value of it here, a wiki/trello or similar is more valuable and makes more sense; as you are tracking a lot of abstract ideas.
As soon as you start writing code - you should start the version control process; and through out the development phase before you have deployed you continue to use version control; this is where you start getting value out of it. Especially if you are developing with others. If you are a solo developer, version control may seem like extra work for no use; this is debatable, but when you are working in a team it is essential.
Once the project has deployed; revision control is critical and mandatory. You simply cannot afford to not have it - version control offers you lots of benefits for the type of work you undertake after deployment. Bugfixes, automated testing, deployment - these can easily be automated from your version control system. If you didn't use version control during development; now is the best time to deploy it since you have a solid codebase as your reference point.
Version control is so simple these days with mercurial/git and their online hosting services that it is costs nothing to get started; and the benefits far outweigh any drawbacks.
The question is quite abstract. So, an equally abstract answer.
I think you should use version control on a specific project as soon as it starts to add value.
If you can distinguish between two phases - proof of concept/prototype etc., and product code, I think you should separate the code bases for the two. And you can use version control tools for both (source backup first, then real version control), just avoiding cluttering the production repository with early stuff.
If you are using version control just for the code, you could ask that question.
But ideally, version control should help you reproduce a build, which means the configuration files and other settings can be as important as your first line of code.
See for instance ".classpath and .project - check into version control or not?.
That is the kind of data which will facilitate collaboration, as other developers will be up and running (ie able to build your program) very quickly.
I have decided to finally nail down my team's deployment processes, soup-to-nuts. The last remaining pain point for us is managing database and runtime data migration/management. Here are two examples, though many exist:
If releasing a new "Upload" feature, automatically create upload directory and configure permisions. In later releases, verify existence/permissions - forever, automatically.
If a value in the database (let's say an Account Status of "Signup") is no longer valid, automatically migrate data in database to proper values, given some set of business rules.
I am interested in implementing a framework that allows developers to manage and deploy these changes with the same ease that we manage and deploy our code.
So the first question is: 1. What tools/frameworks are out there that provide this capacity?
In general, this seems to be an issue in any given language and platform. In my specific case, I am deploying a .NET MVC2 application which uses Fluent NHibernate for database abstraction. I already have in my deployment process a tool which triggers NHibernate's SchemaUpdate - which is awesome.
What I have built up to address this issue in my own way, is a tool that will scan target assemblies for classes which inherit from a certain abstract class (Deployment). That abstract class exposes hooks which you can override and implement your own arbitrary deployment code - in the context of your application's codebase. the Deployment class also provides for a versioning mechanism and the tool manages the current "deployment version" of a given running app. Then, a custom NAnt task glues this together with the NAnt deployment script, triggering the hooks at the appropriate times.
This seems to work well, and does meet my goals - but here's my beef, and leads to my second question: 2. Surely what I just wrote has to already exist. If so, can you point me to it? and 3. Has anyone started down this path and have insight into problems with this approach?
Lastly, if something like this exists, but not on the .NET platform, please still let me know - as I would be more interested in porting a known solution than starting from zero on my own solution.
Thanks everyone, I really appreciate your feedback!
Each major release, have a script to create the environment with the exact requirements you need.
For minor releases, have a script that is split into the various releases and incrementally alters the environment. There are some big benefits to this
You can look at the changes to the environment over time by reading the script and matching it with release notes and change logs.
You can create a brand new environment by running the latest major and then latest minor scripts.
You can create a brand new environment of a previous version (perhaps for testing purposes) by specifying it to stop at a certain minor release.
Given a large scale software project with several components written in different languages, configuration files, configuration scripts, environment settings and database migration scripts - what are the common practices for deployment to production?
What are the difficulties to consider? Can the process be simplified with tools like Ant or Maven? How can rollback and database management be handled? Is it advisable to use version control for the production environment?
As I see it, you're mostly asking about best practices and tools for release engineering AKA releng -- it's important to know the "term of art" for a subject, because it makes it much easier to search for more information.
A configuration management system (CMS -- aka revision control system or version control system) is indispensable for today's software development; if you use one or more IDEs, it's also nice to have good integration between them and the CMS, though that's more of an issue for purposes of development than for purposes of deployment / releng.
From a releng viewpoint, the key thing about a CMS is that it must have good support for "branching" (under whatever name), because releases must be made from a "release branch" where all the code under development and all of its dependencies (code and data) are in a stable "snapshot" from which the exact, identical configuration can be reproduced at will.
The need for good branching support may be more obvious if you have to maintain multiple branches (customized for different uses, platforms, whatever), but even if your releases are always, strictly in a single linear sequence, releng best practices still dictate making a release branch. "Good branching support" includes ease of merging (and "conflict resolution" when different changes are made to a file), "cherry-picking" (taking one patch or changeset from one branch, or the head/trunk, and applying it to another branch), and the like.
In practice, you start off the release process by making a release branch; then, you run exhaustive testing on that branch (typically MUCH more than what you run everyday in your continuous build -- including extensive regression testing, integration testing, load testing, performance verification, etc, and possibly even more costly quality assurance processes, depending). If and when the exhaustive testing and QA reveal defects in the release-candidate (including regressions, performance degradation, etc), they must be fixed; in a large team, development on head/trunk may be continuing while the QA is being done, whence the need for ease of cherry-picking / merging / etc (whether your practice is to perform the fix on head or on the release branch, it still needs to be merged to the other side;-).
Last but not least, you're NOT getting full releng value from your CMS unless you're somehow tracking with it "everything" that your releases depend on -- simplest would be to have copies or hard links to all the binaries for the tools you need to build your release, etc, but that may often be impractical; so at the very least track the exact release, version, bugfix &c numbers of those tools that are used (operating system, compilers, system libraries, tools that preprocess image, sound or video files into final form, etc, etc). The key is being able, at need, to exactly reproduce the environment required to rebuild the exact version that's proposed for release (otherwise you'll go mad tracking down subtle bugs that may depend on third party tools' changes as their versions change;-).
After a CMS, the second most important tool for releng is a good issue tracking system -- ideally one that's well integrated with the CMS. That's also important for the development process (and other aspects of product management), but in terms of the release process the importance of the issue tracker is the ability to easily document exactly what bugs have been fixed, what features have been added, removed, or changed, and what modifications in performance (or other user-observable characteristics) are expected in the new forthcoming release. For the purpose, a key "best practice" in development is that every changeset that gets committed to the CMS must be connected to one (or more) issue in the issue tracking system: after all, there's gotta be some purpose for that change (fix a bug, change a feature, optimize something, or some internal refactor that's supposed to be invisible to the software's user); similarly, every tracked issue that's marked as "closed" must be connected to one (or more) changesets (unless the closing is of the "won't fix / working as intended" kind; issues related to bugs &c in third-party components, which have been fixed by the third-party supplier, are easy to treat similarly if you do manage to keep track of all third-party components in the CMS too, see above; if you don't, at least there should be text files under CMS documenting third-party components and their evolution, again see above, and they need to be changed when some tracked issue on a 3rd party component gets closed).
Automating the various releng processes (including building, automated testing, and deployment tasks) is the third top priority -- automated processes are much more productive and repeatable than asking some poor individual to manually go through a list of steps (for sufficiently complex tasks, of course, the workflow of the automation may need to "get a human being in the loop"). As you surmise, tools such as Ant (and SCons, etc, etc) can help here, but inevitably (unless you're lucky enough to get away with very simple and straightforward processes) you'll find yourself enriching them with ad-hoc scripts &c (some powerful and flexible scripting language such as perl, python, ruby, &c, will help). A "workflow engine" can also be precious when your release workflow is sufficiently complex (e.g. involving specific human beings or groups thereof "signing off" on QA compliance, legal compliance, UI guidelines compliance, and so forth).
Some other specific issues you're asking about vary enormously depending on specifics of your environment. If you can afford programmed downtime, your life is relatively easy, even with a large database in play, as you can operate sequentially and deterministically: you shut the existing system down gracefully, ensure the current database is saved and backed up (easing rollback, in the hopefully VERY rare case it's needed), run the one-off scripts for schema migration or other "irreversible" environment changes, fire the system back up again in a mode that's still unaccessible to general users, run another extensive suite of automated tests -- and finally if everything's gone smoothly (including the saving and backup of the DB in its new state, if relevant) the system's opened up to general use again.
If you need to update a "live" system, without downtime, this may range anywhere from a slight inconvenience to a systematic nightmare. In the best case, transactions are reasonably short, and synchronization between the state set by transactions may be delayed a bit without damage... and you have a reasonable abundance of resources (CPUs, storage, &c). In this case, you run two systems in parallel -- the old one and the new one -- and just make sure all new transactions target the new system, while letting old ones complete on the old system. A separate task periodically syncs "new data in the old system" to the new system, as transactions on the old system terminate. Eventually you can determine that no transactions are running on the old system and all changes that happened there are synced up to the new one -- and at that time you can finally shut down the old system. (You need to be prepared to "reverse sync" too of course, in case a rollback of the change is needed).
This is the "simple, sweet" extreme for live system updating; at the other extreme, you can find yourself in such an overconstrained situation that you can prove the task is impossible (you just cannot logically meet all the stated requirements with the given resources). Long sessions opened on the old system which just cannot be terminated -- scarce resources that make it impossible to run two systems in parallel -- core requirements for hard-real-time sync of every transaction -- etc, etc, can all make your life miserable (and as I noticed, at the extreme, can make the stated task absolutely impossible). The two best things you can do about this: (1) ensure you have abundant resources (this will also save your skin when some server unexpected goes belly-up... you'll have another one to fire up to meet the emergency!-); (2) consider this predicament from the start, when initially defining the architecture of the overall system (e.g.: prefer short-lived transactions to long-lived sessions that just can't be "snapshot, closed down, and restarted seamlessly from the snapshot", is one good arcitectural pointer;-).
disclaimer: where I work we use something I wrote that I'm going to mention
I'll tell you how I do it.
For configuration settings, and general deployment of code and content, I use a combination of NAnt, a CI server, and dashy (an automatic deployment tool). You can replace dashy with any other 'thing', that automates the uploads to your server (perhaps capistrano).
For DB scripts, we use RedGate SQL Compare to get the scripts, and then for most changes, I actually make them manually, where appropriate. This is because some of the changes are slightly complex, and I feel more comfortable doing it by hand. You can actually use this tool to do it for you, (or at least generate the scripts).
Depending on your language, there are some tools that can script the DB updates for you (I think someone on this forum wrote one; hopefully he'll reply), but I have no experience with those. It's something I'd like to add though.
Difficulties
I forgot to answer one of your questions.
The biggest problem in updating any significantly complicated/distributed site is DB synchronisation. You need to consider if you will have any downtime, and if you do, what will happen to the DBs. Will you shutdown everything, so that no transactions can be processed? Or will you shift everything to one server, update DB B, and then sync DB A & B, then update DB B? Or something else?
Whatever you choose, you need to choose it, and either say "Okay for each update, there will be X downtime", or whatever. Just have it documented.
The worst thing you can do is have someones transaction fail, mid processing, because you were updating that server; or to somehow leave only part of your system operational.
I don't think you have any option about using versioning or not.
You cannot go without versioning (as mentioned in a comment).
I am talking from experience since I am currently working on a website where we have several items that have to work together:
The software itself, its functionalities at a given point in time
The external systems (6 of them) we are linked with (messages are versioned)
A database, which holds the configuration (and translations)
The static resources (images, css, javascripts) hosted on an Apache server (several in fact)
A java applet, which has to be synchronized with the javascript and software
This works because we use versioning, although I must admit that our database is pretty simple, and because the deployment is automated.
Versioning means that we have actually at any point in time several concurrent versions of the messages, the database, the static resources and the java applet.
It is especially important in the event of a 'fallback'. If you discover a flaw when loading you new software and suddenly you cannot afford to load, you'll have a crisis if you have not versioned, and you'll just have to load the old soft if you have.
Now as I said, the deployment is scripted:
- the static resources are deployed first (+ the java applet)
- the database goes next, several configurations cohabit since they are versioned
- the soft is queued for load in a 'cool' time-window (when our traffic is at its lowest point, so at night)
And of course we take care of backward / forward compatibility issues with the external servers, which should not be underestimated.
We are in the process of selecting a workflow solution for a company that uses Microsoft products end to end. Given the news on WF4, in that it seems to be essentially a rewrite of previous versions, is it a wise move to back the current version or should we be looking elsewhere?
Ie - is the current version so bad that we would not be wise to try and use it?
Haiving just launched a project which .NET 3.5 and workflow I'd say that the current release of WF is good enough to use and run with. It has helped us to get a product out quickly (we have the usual feature creep and requirements changing weekly). However, I have a list of complaints with it:
The workflow designer will drive you insane because it is so slow (in certain circumstances) and re-arranges your state machines as it sees fit.
There is no built in upgrade strategy for keeping your old workflows running once you do a bug fix release. If you are going to use WF think carefully how to do upgrades early.
Itegrating with WCF (the send and recieve activity) hide the WorkflowRuntime from you this makes it very difficult to understand what is going on on the hood.
Its not easy to unit test them. There are ideas out there but none seemed particulary easy when we started this WorkFlow Unit Testing
I like the ideas and potential of Workflow based development, however I am not in a hurry to repeat this experience and would probably stick without it for long running processes. One place I would use it again would be in a short, complicated process (like a rules engine for working out prices).
Maybe it is a little late for you, but now that WF 4.0 is released in beta, other people thinking the same question can consider backing the 4.0 horse instead of 3.5 horse.
This goes some way to fixing the following problems:
•The workflow designer will drive you insane because it is so slow (in certain circumstances) and re-arranges your state machines as it sees fit.
[Designer Perf Improved]
•Its not easy to unit test them. There are ideas out there but none seemed particulary easy when we started this WorkFlow Unit Testing
[I think it's a little easier now, some of the introduction to workflow samples include plenty of unit testing]
My understanding is that Microsoft will provide backwards compatibility and/or a migration strategy to the new WF, so I would guess that you are safe to use it. However, I have heard from other developers in my organization that the current version of WF is extremely painful to use. If you have the budget (and depending on the complexity of your workflows), you may want to consider K2: http://www.k2.com/en/index.aspx
I, as a workflow developer, think that current version is painful to use. This is not surprising as this is a v1.0 software out from microsoft :)
I think you should first consider your expectations from a workflow software. Do you have a well defined list of expectations from WF? Acutally I am wondering content of such a list. Maybe we can help more detailed on each topic.
I don't know why people have such negative impressions about WF. Sure it has it drawbacks, but I thought it was pretty useful. The one major issue I have about it is the lack of support for upgrading existing workflow (bullent #2 in gbanfill's list).
Another point to use the current version is that "Dublin" (Microsoft new App Server) will be built on WCF & WF .NET 4.0 but will gladly host 3.5 WF's. So you will be able to migrate to that without a rewrite.
Just a quick note to mention that Visual Studio 2010 CTP contains a new updated WF designer as part of the Oslo objective.