Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run Quartz.NET Jobs in a separate AppDomain?

Tags:

quartz.net

Is it possible to run Quartz.NET jobs in a separate AppDomain? If so, how can this be achieved?

like image 964
Brad Leach Avatar asked Dec 05 '11 22:12

Brad Leach


1 Answers

Disclaimer: I've not tried this, it's just an idea. And none of this code has been compiled, even.

Create a custom job factory that creates a wrapper for your real jobs. Have this wrapper implement the Execute method by creating a new app domain and running the original job in that app domain.

In more detail: Create a new type of job, say IsolatedJob : IJob. Have this job take as a constructor parameter the type of a job that it should encapsulate:

internal class IsolatedJob: IJob
{
    private readonly Type _jobType;

    public IsolatedJob(Type jobType)
    {
        _jobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
    }

    public void Execute(IJobExecutionContext context)
    {
        // Create the job in the new app domain
        System.AppDomain domain = System.AppDomain.CreateDomain("Isolation");
        var job = (IJob)domain.CreateInstanceAndUnwrap("yourAssembly", _jobType.Name);
        job.Execute(context);
    }
}

You may need to create an implementation of IJobExecutionContext that inherits from MarshalByRefObject and proxies calls onto the original context object. Given the number of other objects that IJobExecutionContext provides access to, I'd be tempted to implement many members with a NotImplementedException as most won't be needed during job execution.

Next you need the custom job factory. This bit is easier:

internal class IsolatedJobFactory : IJobFactory
{
    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return NewJob(bundle.JobDetail.JobType);
    }

    private IJob NewJob(Type jobType)
    {
        return new IsolatedJob(jobType);
    }
}

Finally, you will need to instruct Quartz to use this job factory rather than the out of the box one. Use the IScheduler.JobFactory property setter and provide a new instance of IsolatedJobFactory.

like image 103
Josh Gallagher Avatar answered Nov 11 '22 07:11

Josh Gallagher