private JobScriptInitializeResult InitializeAndStartRunningHandler(out RunningHandlerProxy handlerProxy) { // Create a proxy for the handler handlerProxy = (RunningHandlerProxy)_appDomain.CreateInstanceAndUnwrap(typeof(RunningHandlerProxy).Assembly.FullName, typeof(RunningHandlerProxy).FullName, false, BindingFlags.Default, null, new object[] { Id, _packageManager.PackageBaseFolder }, null, null); // Create a interchangeable event sink to register cross-domain events to catch logging events var sink = new EventSink <LogEventArgs>(); handlerProxy.RegisterLogEventSink(sink); sink.NotificationFired += (sender, args) => _logger.Log(args.LogEntry.SetHandlerId(Id)); // Register event sink to listen on state changes var stateSink = new EventSink <RunningHandlerStateChangedEventArgs>(); handlerProxy.RegisterStateChangedEventSink(stateSink); stateSink.NotificationFired += (sender, args) => { if (args.State == RunningHandlerState.Failed) { SetFailed(); } else if (args.State == RunningHandlerState.Finished) { SetFinished(); } }; // Initialize the handler var initParams = new RunningHandlerInitializeParams { HandlerSettings = HandlerSettings, JobHash = JobScript.Hash, PackageName = JobScript.PackageName, JobAssemblyPath = JobScriptAssembly }; var initResult = handlerProxy.InitializeAndStart(initParams); return(initResult); }
/// <summary> /// Initializes the handler and everything it needs to run /// </summary> public JobScriptInitializeResult InitializeAndStart(RunningHandlerInitializeParams runningHandlerInitializeParams) { // Initialization _jobScriptHash = runningHandlerInitializeParams.JobHash; var packageName = runningHandlerInitializeParams.PackageName; var currentPackageFolder = _packageManager.GetPackagePath(packageName); // Preparations var result = new JobScriptInitializeResult(); // Assign the path to the output assembly var jobAssemblyPath = runningHandlerInitializeParams.JobAssemblyPath; // Read the settings IHandlerCustomSettings customSettings; JobFileHandlerSettingsReader.LoadAssemblyAndReadSettings(jobAssemblyPath, out _handlerSettings, out customSettings); // Read the package information object var packageInfo = _packageManager.GetInfo(packageName); // Search for the correct handler type in the given assemblies Type handlerType = null; foreach (var handlerAssemblyName in packageInfo.HandlerAssemblies) { // Load the assembly var handlerAssemblyPath = Path.Combine(currentPackageFolder, handlerAssemblyName); var handlerAssembly = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(handlerAssemblyPath)); // Try loading the from the assembly Type[] types; try { types = handlerAssembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { result.SetError(AddJobScriptError.TypeException, ex.LoaderExceptions.First().Message); return(result); } // Search for the correct handler type foreach (var type in types) { if (typeof(IHandler).IsAssignableFrom(type)) { var att = type.GetCustomAttribute <HandlerNameAttribute>(true); if (att != null) { if (att.HandlerName == _handlerSettings.HandlerName) { handlerType = type; break; } } } } if (handlerType != null) { break; } } if (handlerType == null) { result.SetError(AddJobScriptError.JobScriptMissing, String.Format("Handler type for handler '{0}' not found", _handlerSettings.HandlerName)); return(result); } // Initialize the handler var handlerInstance = (IHandler)Activator.CreateInstance(handlerType); // Initialize the handler with the custom settings handlerInstance.InitializeCustomSettings(customSettings); // Attach to the logger handlerInstance.Logger.LogEvent += (sender, args) => Logger.Log(args.LogEntry.SetHandlerId(Id)); // Call the virtual initialize method handlerInstance.Initialize(); // Event when a job was added handlerInstance.EnqueueJobEvent += EnqueueJob; // Assign the handler _handler = handlerInstance; // Start the control thread _controlTaskCancelToken = new CancellationTokenSource(); _controlTask = new Task(ControlThread, _controlTaskCancelToken.Token); _controlTask.ContinueWith(t => { Logger.Fatal(t.Exception, "Handler: '{0}' has exception", Id); TearDown(true); OnStateChangedEvent(new RunningHandlerStateChangedEventArgs(RunningHandlerState.Failed)); }, TaskContinuationOptions.OnlyOnFaulted); _controlTask.Start(); // Notify the start event _handler.OnStart(); // Fill and return the info object result.HandlerId = Id; return(result); }