none
Registering RoleEnvironmentChanged

    Question

  • Hi All!

    I have a singleton class that caches some connection information. But when the configuration file changes that class should get new information.

    What is the best practice in this scenario? Can I register RoleEnvironment.Changed in the constructor of the class? (I tried but apparently is not being triggered)

    Thanks!

    dan


    dfirka
    Tuesday, April 19, 2011 6:57 PM

Answers

  • Dan,

    This is not working as expected because your windows azure app is probably running under full IIS and the information you are needing is not available to process your app is running in.  To help solve your problem head on over to  (http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx).

    Excerpt

    "When you create your web role project, Visual Studio creates a web.config file for your .NET configuration. While your web application can access this information, your RoleEntryPoint code cannot-because it's not running as a part of your web site. As mentioned earlier, it runs under a process called WaIISHost.exe, so it expects its configuration to be in a file called WaIISHost.exe.config.  Therefore, if you create a file with this name in the your web project and set the "Copy to Output Directory" property to "Copy Always" you'll find that the RoleEntryPoint can read this happily. This is one of the only cases I can think of where you'll have two .NET configuration files in the same project!"

    Thanks,

    Apollo

    • Marked as answer by dfirka Wednesday, April 20, 2011 1:26 PM
    Tuesday, April 19, 2011 9:50 PM
  • Hello Dan,

    From Apollo's (thanks Apollo) post, you can understand that actually the web application and RoleEntryPoint code are running in separated processes.

    But you mean reading connection information from ServiceConfiguration.cscfg and not web.config file. Right?

    If so, I think registering RoleEnvironment.Changed event in the constructor of the singleton class will be fine. When the class is firstly called, the constructor will be triggered, and a method of the class will be handling the RoleEnvironment.Changed event. If the configuration is changed, the event handler will be triggered as espected.

    However, if you are not explicitly handling RoleEnvironment.Changing event, the default implementation in the Visual Studio templates restarts on all configuration changes. That means, when the configuration is changed, the instances will be restarted and the memory will be refreshed. Thus, the web application will restart and constructor will be triggered again just as at the first time - a total restart of the application.

    To cancel the restart of instance, I suggset handling RoleEnvironment.Changing as well. Code snippet will be:

    void RoleEnvironment_Changing(object sender, Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironmentChangingEventArgs e)
    {
     e.Cancel = false;
    }
    

    Thanks,


    Wengchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

    • Edited by Wenchao Zeng Wednesday, April 20, 2011 9:37 AM typo
    • Marked as answer by dfirka Wednesday, April 20, 2011 1:26 PM
    Wednesday, April 20, 2011 9:32 AM

All replies

  • Dan,

    This is not working as expected because your windows azure app is probably running under full IIS and the information you are needing is not available to process your app is running in.  To help solve your problem head on over to  (http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx).

    Excerpt

    "When you create your web role project, Visual Studio creates a web.config file for your .NET configuration. While your web application can access this information, your RoleEntryPoint code cannot-because it's not running as a part of your web site. As mentioned earlier, it runs under a process called WaIISHost.exe, so it expects its configuration to be in a file called WaIISHost.exe.config.  Therefore, if you create a file with this name in the your web project and set the "Copy to Output Directory" property to "Copy Always" you'll find that the RoleEntryPoint can read this happily. This is one of the only cases I can think of where you'll have two .NET configuration files in the same project!"

    Thanks,

    Apollo

    • Marked as answer by dfirka Wednesday, April 20, 2011 1:26 PM
    Tuesday, April 19, 2011 9:50 PM
  • Hello Dan,

    From Apollo's (thanks Apollo) post, you can understand that actually the web application and RoleEntryPoint code are running in separated processes.

    But you mean reading connection information from ServiceConfiguration.cscfg and not web.config file. Right?

    If so, I think registering RoleEnvironment.Changed event in the constructor of the singleton class will be fine. When the class is firstly called, the constructor will be triggered, and a method of the class will be handling the RoleEnvironment.Changed event. If the configuration is changed, the event handler will be triggered as espected.

    However, if you are not explicitly handling RoleEnvironment.Changing event, the default implementation in the Visual Studio templates restarts on all configuration changes. That means, when the configuration is changed, the instances will be restarted and the memory will be refreshed. Thus, the web application will restart and constructor will be triggered again just as at the first time - a total restart of the application.

    To cancel the restart of instance, I suggset handling RoleEnvironment.Changing as well. Code snippet will be:

    void RoleEnvironment_Changing(object sender, Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironmentChangingEventArgs e)
    {
     e.Cancel = false;
    }
    

    Thanks,


    Wengchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

    • Edited by Wenchao Zeng Wednesday, April 20, 2011 9:37 AM typo
    • Marked as answer by dfirka Wednesday, April 20, 2011 1:26 PM
    Wednesday, April 20, 2011 9:32 AM
  • Thanks!

    To clarify the situation: when running on premises, the singleton class feeds from the web.config. However, to prevent innecesary redeploys, on Azure the class gets the information from an xml file stored as a blob.

    When we modify the xml, updating the blob, we also modify a "flag" configuration setting in ServiceConfiguration.cscfg; the change in this file then triggers code that asks the singleton class to refresh the data from the blob. That way, when we have changes in our config (a new tenant, or different info for an existing tenant) we dont have to redeploy the full service.

    (BTW we are not using VS, we are packaging manually through CSPACK to be able to create on-premises and on-cloud releases from the same binary set)

    I think we'll rely on setting the Cancel=true flag, because I wasnt succesfull getting RoleEnvironmentChanged called in the singleton, up to now.

    (also the singleton is being held in the Cache of httpContext)

    thanks!

    df


    dfirka
    Wednesday, April 20, 2011 1:35 PM
  • Hi dfirka,

    If we set the Cancel=true, all instances will restart. Thus, the updated configuration will be read in the start of the applicaion causing that no need to handle RoleEnvironmentChanged anymore. So I think it is an workable solution.

    Thanks,


    Wengchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    Thursday, April 21, 2011 1:50 AM