So, I finally got Project Thor to a state where I felt comfortable deploying it to the Azure staging environment. After packaging it up, uploading it to the portal, pressing run, I waited with baited breath as my web role and worker role fired up. And I waited, and I waited, and I waited. Both roles went from Initializing to Busy to Stopping to Stopped. Of course, they work on my machine without problem. FAIL!
I have a bunch of logging in place, but the roles weren’t even getting to the point where they could log messages. After doing some digging on the Azure forums I came across this post. The underlying idea is that my apps were missing referenced assemblies. I saw this as a pretty good possibility as my apps are loosely coupled and I’m actually dropping assemblies into various directories as part of a post build process. However, my assumption was that the CSPack command line utility was simply packaging up the web and worker role directories for deployment. I wanted to verify my assumption was incorrect before proceeding, but since the package created by CSPack is encrypted there’s no way for me to verify the contents. Or is there?
Enter Jim Nakashima. Jim has a great poston how you can force CSPack to create unencrypted packages. After following the steps in the post and creating the unencrypted package, I dug into it to examine the contents. Sure enough, the assemblies I was dropping into my web and worker role directories weren’t getting packaged. After reading this post by JimI understood why. If I want to include the files in the package they need to be associated with the projects. This is kind of a bummer as I wanted to maintain the loose coupling, but I was willing to sacrifice it for the time being. I added the necessary references to my worker and web roles projects, packaged, uploaded, pressed run, and waited, and waited, and waited. Same thing as before. WTF?!
This post mentions to make sure you have “Copy Local” set to true for your assemblies. OK. Fine. No problem. I went through the web and worker role projects and set all references to “Copy Local” = true, packaged, uploaded, pressed run, and waited, and waited, and waited. OK, progress. The worker role started up, but the web role continued to fail.
I’m not one to typically post a problem on a forum as I like to go through the pain of solving them myself (helps me not to forget). However, at this point I was at my wit’s end. I posted the problem to the Azure forums, making sure to give Microsoft permission to open up my VM for diagnostic purposes.
After a couple of back and fourths, the problem became clear. I had marked all assemblies in my web and worker roles with “Copy Local” = true. However, I’m running a 32 bit dev machine (I know, I know I need to upgrade, but this laptop rocks, but that’s another post), and the cloud runs 64 bit. As a result, the 32 bit assemblies that were included in my package were failing to load as they weren’t 64 bit. Makes perfect sense! OK, so which assemblies are loaded in the cloud and which do I need to set to “Copy Local” = true? The answer lies here, but I’ll summarize it for you:
The cloud has a default installation of .NET 3.5 SP1, plus the Microsoft.Windows.Azure.ServiceRuntime.dll. This means you can refer to C:\Windows\Microsoft.NET\Framework64 on your own machine. All the assemblies available in v2.0.50727, v3.0, and v3.5 should be available on the cloud machines.
Many thanks to Yin-Lun Luo and Toddy Mladenov for the help.
Given the several valuable lessons I learned, I would once again say that Project Thor is living up to its mission.
adam azure, thor azure, thor