I need to change some configuration settings on-the-fly in a Windows Azure project - and they need to be changed via a web service call (updating the application's configuration either via the platform api or the Azure Management site isn't an option here).
The project has multiple web and worker roles - all of which will need to know about the new configuration when it is changed.
The configuration is persisted to durable storage, and it's also cached during runtime in a static variable.
My solution was to create an internal (tcp) endpoint on my roles, and use that to loop through all of the roles and instances within those roles, create a client on the fly, and tell the instance about the new setting. (pretty much identical to: http://msdn.microsoft.com/en-us/gg457891)
At first I started a ServiceHost in the WebRole's RoleEntryPoint... and I was confused why everything seemed to be working fine when I stepped through the communications (the static variables where getting set correctly) - yet when I'd make other webservice calls, the static variable seemed to have "forgotten" what I set it to.
This was the case both locally, and in the Azure staging environment.
At this point I realized that because we're using full-IIS mode, the RoleEntryPoint and the Web Services were running in two separate processes - one in Azure's stub, and one in IIS.
"Not a problem" I said, I'll simply move the line of code which starts the ServiceHost from my RoleEntryPoint into the global.asax - at which point the ServiceHost will have been started in the same process as the rest of the site - and the static variables would be the same ones.
Here's where I'm having a problem; This works great on my local machine running in the dev environment. As soon as I deploy to staging I start getting error emails saying the channel used to connect to the service can't be closed because it's in a "faulted state".
Question:
Follow-Up:
Via remote desktop i've learned several interesting things:
Non-HTTP Activation isn't installed by default on Azure WebRoles. I believe this can be overcome via a startup script:
start /w pkgmgr /iu:WCF-NonHTTP-Activation;
The website created in IIS by the web role doesn't have the net.tcp protocol enabled by default. I also believe this can be overcome with a startup script:
%systemroot%\system32\inetsrv\appcmd.exe set app "Website Name Here" /enabledProtocols:https,http,net.tcp
I haven't had time to take this all the way, as deadlines have forced me to implement some workarounds temporarily.
Some useful links related to this topic:
http://msdn.microsoft.com/en-us/magazine/cc163357.aspx
http://forums.iis.net/t/1160443.aspx
http://msdn.microsoft.com/en-us/library/ms731053.aspx
http://labs.episerver.com/en/Blogs/Paul-Smith/Dates/2008/6/Hosting-non-HTTP-based-WCF-applications-in-IIS7/
UPDATE (6/27/2011):
Amazingly, someone at Microsoft (whose blog I commented on) actually got me an answer on this.
The Azure & WCF teams updated this post:
http://blogs.msdn.com/b/windowsazure/archive/2011/06/27/hosting-services-with-was-and-iis-on-windows-azure.aspx
The link contains all of the information you need to get going with this.
And a HUGE thanks goes to Yavor Georgiev, the MSFT PM with the win.
It's been quite a while since I've asked the question, and no answers, so let me leave this:
Per my follow-ups in the post, there are ways of making this work... but they are complicated and difficult to implement.
For WORKER ROLES, netTcpBinding works perfectly. No issues here. Go ahead and use it.
For WEB ROLES, you've got problems.But netTcpBinding is what you need to use for exposing internal endpoints. What to do?
Well, here's what I did:
It's not perfect... but it works, and it's not terrible.
I suspect that needing to do this kind of thing isn't super common, and I really can't think of any reason why you'd need to other than to dynamically modify settings at runtime... which means you're not slamming these services like crazy.
Obviously, YMMV.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With