Actually, after some further testing with a dummy project, I found the following issue:
I have 1 WorkerRole with the following csdef:
<WorkerRole name="WorkerRole1" vmsize="ExtraSmall">
<Endpoints>
<InternalEndpoint name="InternalEndpoint_DiscoveryService" protocol="tcp" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
<Contents>
<Content destination=".\">
<SourceDirectory path="C:\Development\CloudTest\DiscoveryService\bin\Debug\" />
</Content>
</Contents>
<Startup>
<Task commandLine="startup.cmd" executionContext="elevated" taskType="simple" />
</Startup>
<Runtime executionContext="elevated"></Runtime>
</WorkerRole>
The content copies the executables of a windows service to the approot folder on my azure instance package. Within these files a startup.cmd file is always included, which is being triggered at startup of the azure instance, which installs the windows service
and runs it.
My windows service exists of the following code:
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Persist_Trace_Logging();
Write_Endpoints_ToLog();
}
public static void Write_Endpoints_ToLog()
{
string strLog = "WorkerRole Endpoint settings: \n";
foreach (KeyValuePair<string, Role> keyvRole in RoleEnvironment.Roles)
{
strLog += "For role " + keyvRole.Key + ": \n";
foreach (RoleInstance _RoleInstance in keyvRole.Value.Instances)
{
strLog += "Endpoints " + _RoleInstance.Role.Name + " " + _RoleInstance.Id + ": \n";
foreach (KeyValuePair<string, RoleInstanceEndpoint> keyv in _RoleInstance.InstanceEndpoints)
{
strLog += keyv.Key + ": " + keyv.Value.IPEndpoint.ToString() + "\n";
}
}
strLog += "\n\n";
}
EventLog.WriteEntry("Application", strLog, EventLogEntryType.Information);
}
protected override void OnStop() { }
public static void Persist_Trace_Logging()
{
System.Diagnostics.Trace.Listeners.Add(new Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener());
System.Diagnostics.Trace.AutoFlush = true;
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("UseDevelopmentStorage=true");
DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
config.Logs.ScheduledTransferPeriod = TimeSpan.FromSeconds(10.0);
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Undefined;
config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromSeconds(10.0);
config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.ScheduledTransferLogLevelFilter = LogLevel.Undefined;
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = storageAccount.CreateRoleInstanceDiagnosticManager(RoleEnvironment.DeploymentId, RoleEnvironment.CurrentRoleInstance.Role.Name, RoleEnvironment.CurrentRoleInstance.Id);
roleInstanceDiagnosticManager.SetCurrentConfiguration(config);
DiagnosticMonitor.Start(storageAccount, config);
}
With 1 workerrole, I test this. This works fine.
At my eventlog an entry is written with with the endpoints of this role instance.
Then I added a new (2nd) workerole
<WorkerRole name="WorkerRole2" vmsize="ExtraSmall">
<Runtime executionContext="elevated"></Runtime>
</WorkerRole>
So a very simple second workerrole, which actually does nothing.
Result:
As soon as I run the project, the startup of the windows service fails with the following error:
Service cannot be started. System.InvalidOperationException: Not running in a hosted service or the Development Fabric.
at Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.GetDefaultStartupInfoForCurrentRoleInstance()
at Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener..ctor()
at DiscoveryService.Service1.Persist_Trace_Logging()
So in the startup of my service, I remove the Persist_Logging() method. Clean & Rebuild necessary stuff and I run the cloudproject again.
Following error:
Service cannot be started. System.InvalidOperationException: role discovery data is unavailable
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.get_Roles()
at DiscoveryService.Service1.Write_Endpoints_ToLog()
I tried to play a bit with settings of the roles, removing diagnostics everywhere ... anything ... but I keep getting this above error when working on the RoleEnvironment. Seriously ...
Now I remove workerrole 2 again ... And run the cloud project again.
The windows service starts up correctly again and writes following output to my eventlog:
WorkerRole Endpoint settings:
For role WorkerRole1:
Endpoints WorkerRole1 deployment16(304).CloudTest.WorkerRole1_IN_0:
InternalEndpoint_DiscoveryService: 127.255.0.0:20000
So apparently the issue seems to be when you have 2 workerroles. The windows service seems to catch exceptions on the azure specific stuff when the 2nd workerrole is being run. If there is only 1 workerrole,
the attached windows service just runs fine.
This some issue with the development emulator ? Or perhaps with multiple processes being run with 2 workerroles instead of 1 workerrole ?
Anyone has any clue that could get me past this issue please?
Thanks in advance,
Robbin
Be nice to nerds ... Chances are you'll end up working for one!