Single Servicing
What is Single Servicing?
Single Servicing is that when you fix a bug in your component, you drop a single binary with the fix into customer's machine, everyone using your component automatically get the fix.
Sounds easy. But in reality it is much harder.
1. Applications may statically link to your component. Those applications will have to re-compile to get your fix.
The recent zlib bug is an example.
2. Applications may carry a private copy of your componenent. Those applications will have to re-deploy your new component to their private directory.
The recent GDI+ bug is an example.
You are very screwed.
Well, until you start using managed code. Fortunately, it is very possible to achieve single servicing.
1. Static Linking
You can't statically link an managed assembly. You simply can't. The platform does not support it.
Joel Spolsky asked: " Please Sir May I Have a Linker?". Jason Zander answered: "No". You know, you should be very thankful for that decision.
2. Private Deployment
In Whidbey we made two changes to assembly loading:
Assembly.Load* now apply policy
Assembly.LoadFrom/LoadFile/Load(byte[]) prefers GAC
The two changes together, give you a way to do single servicing in .Net.
If you buy versioning, you change your assembly version number, issue a publish policy, and install your fix to GAC. Everyone picks up the fix.
If you don't buy versioning, you don't change your assembly version number, and install your fix to GAC. Everyone picks it up.
Of course, the bottom line is, you have to strongly name your assembly.
In light of the zlib and GDI+ patching problem, aren't you glad that in .Net you can be assured of single servicing?
Comments
- Anonymous
November 05, 2004
What do you prefer to do distribute the patch to customer machine? msi or write your own exe w/ fusion api? - Anonymous
November 05, 2004
MSI of course. Why do you want to re-invent the wheel? - Anonymous
November 05, 2004
The comment has been removed - Anonymous
November 06, 2004
David,
Yes, we understand the danger of potential applications breaking other applications. It is the fact that you can't patch all the applications scares people. zlib and GDI+ patching problem will happen again. And people will point finger.
You can use ReflectionOnlyLoad/ReflectionOnlyLoadFrom API in your validation scenario. The two changes I mentioned in the main text won't be applied to ReflectionOnly API.
Regarding roll your own installer vs MSI, MSI put a lot of effort into reliablity. You probably want to take advantage of that. It is not that easy to do reliable install/uninstall. Another advantage for MSI is management. You can use Group Policy with MSI. Roll your own is fine, as long as you are willing to tackle the problem ahead. - Anonymous
November 06, 2004
And of course, if you don't buy single serving, don't strongly name your assemblies. If you want to use other people's assemblies, then you have to play other people's rule. - Anonymous
November 06, 2004
Well okay I posted to the previous entry about Load preferring the GAC and I guess this was the post that you said would explain the reasoning.
I think it's a bad idea. You are basically saying that you will never load a private assembly if there is ever a matching assembly in the GAC. If someone is using a private assembly, it usually means "I want to use THAT version and don't you dare ever change it."
I think the problems you will deal with from unexpected assemblies will almost always outweigh the trouble you have to go to patch assemblies in multiple locations.
I personally rarely install assemblies to the GAC in the first place. - Anonymous
November 06, 2004
Josh,
See my comments above. - Anonymous
November 06, 2004
I 100% love this (servicing re-disted bits kills both us and the OSS guys) but I don't see how the suggestion to use ReflectionOnly to solve David's problem would work... they'll use ReflectionOnlyLoad, which will return the EXACT assembly they ask for, they'll verify it's the right one, then they'll call Load with the same parameters and fusion will load a different version!
Is there an API to get the actual location of the assembly that Load would load (without actually loading it, of course ;-) ), so that you can then pass it to ReflectionOnlyLoad to make sure it's the right one before you load it? - Anonymous
November 07, 2004
The comment has been removed - Anonymous
November 07, 2004
Great post, Junfeng. I still have one question: Given that many developers/project managers don't take the project's evolution (versioning) into account when making the initial design, is there a Microsoft-provided PAG or some sort of recommendation for versioning in .NET?
Something defining what "backward compatible" and "forward compatible" means, what a breaking change is and so on. While some of these things are project-dependent, you should take into account that quite a few developers/architects out there know nothing about this. What's your opinion on this? Is there such a PAG/Is Microsoft considering writing one? - Anonymous
November 07, 2004
The comment has been removed - Anonymous
November 07, 2004
Peter,
There is no such API. But of course, you can try to simulate fusion behavior. After all, all fusion probing logics are documented, if not in MSDN, then in my blogs/Suzanne's blog/Alan's blog. - Anonymous
November 08, 2004
This seems like it is taking a weakness of LoadFrom/TrickleDownload and just making it worse with no opt-out. I wouldn't mind this being the default, but I'd really like a way to say "I want this URL to be checked first". Otherwise a customer could install an update to a dll we use and break our product before we have a chance to QA the changes to a third party DLL.
I like the GAC as a default, but I hate the assumption that the GAC always knows better than the developer. - Anonymous
November 08, 2004
You can't have both -- single servicing and private deployment. It directly contradicts each other.
If we did provide an option to opt-out this, then what is the point of making this change? So that everyone can opt-out a security fix, like the GDI+ fix?
Yes, I know developers hate this. But you know what, system administrators always hate that developers assume they know better than system administrators. - Anonymous
November 08, 2004
The comment has been removed - Anonymous
November 08, 2004
If versioning is implemented correctly, this is actually possible today.
Assume you always ship publisher policy with patches, in your application's config file, you can explicitly opt-out the publiser policy, for specific assembly, or for every assembly. Check out the configuration document, and look for <publishPolicy> under <dependentAssembly>, and <assemblyBinding>.
The problem today is that application developers decide that. We want to move to a model that administrators decide that, not developers. - Anonymous
November 09, 2004
It would seem there's someone out there who's never deployed (or written) a .Net app in his life and yet assumes he's smarter than you guys when it comes to this very topic.
http://www.arstdesign.com/BBS/BulletinBoard.php?qs_id=1925
Well, good for a chuckle at least methinks :-) - Anonymous
November 09, 2004
I was thinking about your post these days - is there a tool to check two versions of an assembly and say "The second is backward-compatible with the first one"? Given the amount of metadata .NET assemblies have, it shouldn't be very difficult to check this (when it comes to classes, interfaces, method signatures and so on). - Anonymous
November 10, 2004
Publisher policy is nice, I wish we could use it. We can't, we install a simple bootstrapper application once and have LoadFrom (trickle download) do all the updating from there on out. Hence we can not update the app config file once installed. If you don't cover the corner cases you don't really have a solution. - Anonymous
November 10, 2004
Ovidiu,
You can't. The two versions of an assembly may have the same metadata, but the behavior could be different. Reflection can't tell behavior change. Even if it can, the change of behavior could be a breaking change for some apps, but not for others.
Rob M,
As a developer, you can think about patching. But patching ultimately is administrators' job. If admin installs a patch,and it breaks your applications, admin should go and modify the app.config for you.
Of course, if the admin is not intelligent enough, there is nothing you can do. But in that case, it is even more important to make sure the system is always in safe state. - Anonymous
November 11, 2004
The comment has been removed