I've implemented a solution in Orchard to run background tasks, but the site runs on multiple instances on Windows Azure, so the instance that picks up the next "due" task leases it by marking it with the instance name.
I've seen the TaskLease module and I'm aware of the Sweep Generator, however, we wanted finer control over task scheduling and wanted to use Azure table storage to "lease" the tasks out to the running instance instead of SQL. Also, we needed a method
for the system to recover if a worker process died during a running task - our implementation notices that the task has been running for a long time and if the thread it was running on has gone it'll mark it to be run again. Hence we came up with our own implementation.
It works great on our dev machines and two test environments. It even works well on our test Azure account and the failover account (the one used if our primary deployment becomes unavailable). However, on the live deployment it doesn't work at all. It logs
the following error constantly:
Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed. at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope(Object tag) at Orchard.Environment.WorkContextAccessor.CreateWorkContextScope()
in c:\PatientScrum\Patient2.0\Main\src\Orchard\Environment\WorkContextAccessor.cs:line 55
The error is thrown from a Timer's elapsed event. What could be causing this? I'm
guessing it's because something else that uses the WorkContextAccessor to create a ThreadStaticScopeImplementation of IWorkContextScope using the same thread (?) has disposed of it beforehand (?) but I'm really not sure! I notice a tag of "work"
is passed to the BeginLifetimeScope method call, all i can think of is calling this method with a different tag. I don't really understand exactly how the dependency resolution works when there's no HttpContext so I'm a bit stuck.
Any help would be appreciated, thanks for your time.