I am trying to host a long running workflow service on Azure but I am having problems with correlation.
I have got the timeToUnload and the timeToPersist set to 0 and I have
A few months later and I have found a solution to this problem. The root problem is that Azure names the Web site something different on each role instance; Rather than "Default Web SIte", the web site is called something like NewOrbit.ExVerifier.Web_IN_0_Web
(given a namespace for your web project of NewOrbit.ExVerifier.Web). Workflow uses the website name as part of the algorithm used to calculate the instance key, hence the problem.
The solution is, quite simply, to rename the website during role startup so it is called the same thing on all instances. Fixing the root problem rather than handling the consequences and so obvious I never saw it the first time round.
Here is how you can do this (losely based on this: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx)
In ServiceDefinition.csdef
add a startup task:
...
Setup\Startup.cmd
should have this content:
powershell -command "set-executionpolicy Unrestricted" >> out.txt
In ServiceDefinition.csdef
add this:
...
Create a setup\RoleStart.ps1
file:
write-host "Begin RoleStart.ps1"
import-module WebAdministration
$siteName = "*" + $args[0] + "*"
Get-WebSite $siteName | Foreach-Object {
$site = $_;
$siteref = "IIS:/Sites/" + $site.Name;
try {
Rename-Item $siteref 'MyWebSite'
write-host $siteName + " was renamed"
}
catch
{
write-host "Failed to rename " + $siteName + " : " + $error[0]
}
}
write-host "End RoleStart.ps1"
(replace MyWebSite with whatever you want the website to be called on all the servers).
Create or Edit WebRole.cs in the root of your website project and add this code:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
var startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = @".\setup\rolestart.ps1",
RedirectStandardOutput = true,
UseShellExecute=false,
};
var writer = new StreamWriter("out.txt");
var process = Process.Start(startInfo);
process.WaitForExit();
writer.Write(process.StandardOutput.ReadToEnd());
writer.Close();
return base.OnStart();
}
}
And that should be it. If you spin up multiple web role instances and connect to them with RDP, you should now be able to see that the website is called the same on all the instances and workflow persistence therefore works.