I have a single page app with Angular.js front, web api2 back end, also using Castle Windsor and SignalR.
I am using a c# component on the server that maintains server state. So, on Application_Start() I register the main component with Castle Windsor as Singleton.
IoC.Container.Register(Component.For(typeof(MainManager)).ImplementedBy(typeof(MainManager)).LifeStyle.Singleton);
(however, I tested PerWebRequest and few other lifestyles, but the main problem remains the same, the started task does not quit)
Then in my Web Api, I can execute commands against that instance.
[HttpGet]
public void StartProcess(Params p) {
IoC.Resolve<MainManager>().StartOperation(p);
}
and this also gives me opportunity to stop it from the website by calling another controller method
[HttpGet]
public void Stop() {
IoC.Resolve<MainManager>().RequestStop();
}
This works great for the most part. However, sometimes my application gets in a bad state (for a multitude of reasons, It can get restarted in prod) I can emulate this problem by modifying web.config during running the operation, so a lot of things reset (such as Signal-R connection), but the main operation does not stop running.
(In fact, once my application is in bad state I can no longer call that Stop controller method because MainManager has been reset, so the only way to stop it as of now is to reset the whole IIS. This is certainly not desired)
I am trying to figure out how to detect this state, and terminate the running process.
As one possible solution, I am experimenting with using Bound lifestyle (new in Castle Windsor 3), trying to scope my manager to my web api httpapplication, but no luck yet.
update
I tried making the main task method static
[HttpGet]
public void Start(ForceData data) {
MainManager.Start(data);
}
I believe this should take out the singleton instance out of equation, but the code still runs un-interrupted after touching web.config
update
took the MainManager class out of equation. All my web api method does now is loop + sleep
[HttpGet]
public void Start(ForceData data) {
foreach (var e in data.Members)
{
_log.Info("processing member: {0}", e.Email);
Thread.Sleep(1000);
}
}
this loop is also not interrupted after touching web.config.
So, at this point I am reading about MVC request lifecycle to figure out at which point this request goes zombie rouge
This is by design, as HttpApplication instances are not freed immediately when application restarts,
http://msdn.microsoft.com/en-us/library/vstudio/ms178473%28v=vs.100%29.aspx
In all your sample Web API method, you can see the thread is still busy, which means ASP.NET runtime considers this request is still being processed.