public void ExecuteRequest(string jobId, string pluginName, Version plugInVersion, PerformContext context) { // create a logger var logger = context.CreateLoggerForPerformContext <HangfireManager>(); // This is a 1st pass at preventing duplicate recurring job when the previous execution is still running var job = JobStorage.Current.GetConnection().GetRecurringJobs().Where(j => j.Id == jobId).FirstOrDefault(); if (job != null) { if (job.LastJobState == "Enqueued" || job.LastJobState == "Processing") { logger.Information("This goes to the job console automatically"); logger.Warning("Skipping execution of JobId: {jobId}, it is still running from a previous execution.", jobId); return; } } // dynamically select the correct plug-in assy to use to process the event IPlugIn jobPlugIn = _plugInsManager.GetJobPlugIn(pluginName, plugInVersion).PlugInImpl;; var plugInLoadContextName = AssemblyLoadContext.GetLoadContext(jobPlugIn.GetType().Assembly).Name; logger.Information("Running plugin {pluginInfo} in ALC: {plugInLoadContextName}.", jobPlugIn.GetPlugInInfo(), plugInLoadContextName); try { // call the method on the dynamically selected assy passing in an anonymous action delagate for the logging method var result = jobPlugIn.Execute(context.BackgroundJob.Id, (LOG_LEVEL logLevel, string logMessage) => { switch (logLevel) { case LOG_LEVEL.INFO: logger.Information(logMessage); break; case LOG_LEVEL.WARNING: logger.Warning(logMessage); break; case LOG_LEVEL.ERROR: logger.Error(logMessage); break; } }); // write post execution log message switch (result.StepStatus) { case STD_STEP_STATUS.SUCCESS: logger.Information(result.ReturnMessage); break; case STD_STEP_STATUS.FAILURE: logger.Error(result.ReturnMessage); break; } } catch (Exception ex) { logger.Error($"Unhandled exception occured in plugin: [{ex.ToString()}]"); } finally { if (jobPlugIn != null) { jobPlugIn = null; } } }