Skip to content
This repository was archived by the owner on Nov 1, 2018. It is now read-only.
This repository was archived by the owner on Nov 1, 2018. It is now read-only.

IIS does not restart the application after it is killed #1425

Closed
@kevinlo

Description

@kevinlo

Hi,

I have application A.exe that is run under IIS. A.exe will start a B.exe which listen to a websocket URL.

At first, when A.exe is hosted in IIS, it has problem to start B.exe because of the Exception_PrefixAlreadyRegistered. After some debugging, I find out the CreateDefaultBuilder will call UseIISIntegration which makes it ignore the UseUrls and use the ASPNETCORE url and port. I fix it by creating a new WebHostBuilder and do most of the calls in the CreateDefaultBuilder, except the UseIISIntegration.

I also find out I need to call UseSetting(WebHostDefaults.PreventHostingStartupKey, "true") or it will load the hosting assembly to UseIIsIntegration. Here is what I have:

            var builder = new WebHostBuilder()
                        .UseHttpSys()
                        .UseUrls(urls)
                        .UseSetting(WebHostDefaults.PreventHostingStartupKey, "true")
                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .ConfigureAppConfiguration((hostingContext, config) =>
                        {
                            var env = hostingContext.HostingEnvironment;

                            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                                  .AddEnvironmentVariables();

                            if (env.IsDevelopment())
                            {
                                var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                                if (appAssembly != null)
                                {
                                    config.AddUserSecrets(appAssembly, optional: true);
                                }
                            }

                            if (args != null)
                            {
                                config.AddCommandLine(args);
                            }
                        })
                        .ConfigureLogging((hostingContext, logging) =>
                        {
                            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                            logging.AddConsole();
                            logging.AddDebug();
                        })
                        .UseDefaultServiceProvider((context, options) =>
                        {
                            options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
                        })
                        .UseStartup<Startup>();
            builder.Build().Run();

It works find after that. A.exe can be launched by IIS and A.exe can start B.exe.

However, when I use the Task Manager to kill A.exe and then I make the request to the IIS to run A, IIS does not re-launch A.exe.

After some debugging to the aspnetcore.dll, I find out when the A.exe is killed, the SERVER_PROCESS::HandleProcessExit will be called. It calls the CheckIfServerIsUp which calls the GetExtendedTcpTable and check if there is a TCP endpoint matching the port A.exe is listening.

The problem is, even A.exe is killed, it still has an endpoint listening to that port with A's process id. Therefore, the aspnetcore thinks A.exe still exists and it does not start a new one when the request comes in.

If I kill the B.exe first and then kill A.exe, that TCP endpoint does not exist and A.exe will be restarted by IIS when the request comes in.

I don't know why starting B.exe (which uses a different url and port from A.exe) will create a TCP endpoint that uses A's port and process id. I try to make B not doing anything and just has A to start B. The problem still exists.

I suspect there is something done by default in the hosting or UseHttpSys that make B adding that TCP endpoint using its host (A) process id and port.

Can anyone tell me how the TCP endpoint is created or give me some clues where I should look at?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions