Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hot deployment of .net assemblies

We have an application running as a Windows service on a production server. The application is partitioned into several assemblies mostly on deployment boundaries. I would like to streamline the deployment of hot-fixes to application assemblies. Currently I do the following steps to deploy a hot fix. (we have a duplicate of the production environment for staging, so everything has to be done twice)

  1. Login to server
  2. Stop the service
  3. Backup currently deployed dll
  4. Replace with hotfix (Copy hotfix over existing dll)
  5. Restart service
  6. Roll back in case of unexpected load errors (has not happened, yet)

I think that what I would like is to upload (SFTP) a dll to a preset folder and have the application pick up the new dll.

One solution I've considered is to have a separate service running on the server. Let's call it a hotfix deployment service. It would watch the file system for new files and do steps 2-6 from the list above.

Any insight is appreciated. I'm open to other alternatives as well as long as they reduce the deployment friction.

like image 577
Kim Major Avatar asked Dec 07 '09 19:12

Kim Major


2 Answers

Having a separate service is probably your best option.

You could, potentially, do this in a single service. The "trick" that would be required to making a service self-updating, though, is a bit difficult to implement.

What you would have to do is have your service start off as nothing but a very lightweight shell service. It could then start a separate, insulated AppDomain, and have that appdomain load your service's assemblies, and initialize, and run.

Later, when you wanted to update (which could trigger via any event the service can pick up, including copy of the new assemblies to an update folder [via FileSystemWatcher], explicitly telling it via networking, etc]), it would need to trigger a way to tell the internal AppDomain's type to stop, then unload the AppDomain. At this point, it could do steps 3 & 4 above. Then, it'd just need to reload the AppDomain, rerun it's initialization, etc.

Since the service would be in a separate AppDomain, this could all happen in one executable, without the service stopping. When an AppDomain is unloaded, the assemblies it loads are also unloaded.

The only requirement here that makes it difficult is that you have to make sure not to pass any types into the main AppDomain from the constructed one, or you'll load the assemblies into your main AppDomain. This would prevent you from being able to update them at runtime.

like image 135
Reed Copsey Avatar answered Sep 21 '22 01:09

Reed Copsey


From our build server, we use a powershell script to remotely stop the service, copy out the new file, and restart the service.

like image 43
David Avatar answered Sep 23 '22 01:09

David