internal static bool IsDisabled(MethodInfo method, INameResolver nameResolver, IJobActivator activator) { ParameterInfo triggerParameter = method.GetParameters().FirstOrDefault(); if (triggerParameter != null) { // look for the first DisableAttribute up the hierarchy DisableAttribute disableAttribute = TypeUtility.GetHierarchicalAttributeOrNull<DisableAttribute>(triggerParameter); if (disableAttribute != null) { if (!string.IsNullOrEmpty(disableAttribute.SettingName)) { return IsDisabledBySetting(disableAttribute.SettingName, method, nameResolver); } else if (disableAttribute.ProviderType != null) { // a custom provider Type has been specified return IsDisabledByProvider(disableAttribute.ProviderType, method, activator); } else { // the default constructor was used return true; } } } return false; }
public MessengerServer(SqlServerSettings settings, RepositoryFactory repositoryFactory) : base(settings) { _repositoryFactory = repositoryFactory; if (settings == null) throw new ArgumentNullException(nameof(settings)); if (string.IsNullOrWhiteSpace(settings.ConnectionString)) throw new NullReferenceException("ConnectionString is not specified!"); _jobActivator = settings.JobActivator ?? new JobActivator(); _checkInterval = settings.CheckInterval.HasValue && settings.CheckInterval > TimeSpan.Zero ? settings.CheckInterval.Value : TimeSpan.FromSeconds(10); _maxProcessCount = settings.MaxProcessCount > 0 ? settings.MaxProcessCount : Environment.ProcessorCount*2; _messageBatchSize = settings.MessageBatchSize > 0 ? settings.MessageBatchSize : 10; _processNameFormat = settings.ProcessNameFormat; _customProcessName = settings.CustomProcessName; _completedMessages = settings.CompletedMessages ?? CompletedMessages.Default; if (_completedMessages.Archive && _completedMessages.Cleanup && _completedMessages.CleanOlderThanUtc == null) { _completedMessages.CleanOlderThanUtc = () => DateTime.Today; } }
public HostListenerFactory(IEnumerable<IFunctionDefinition> functionDefinitions, SingletonManager singletonManager, IJobActivator activator, INameResolver nameResolver, TraceWriter trace) { _functionDefinitions = functionDefinitions; _singletonManager = singletonManager; _activator = activator; _nameResolver = nameResolver; _trace = trace; }
public FunctionIndexProvider(ITypeLocator typeLocator, ITriggerBindingProvider triggerBindingProvider, IBindingProvider bindingProvider, IJobActivator activator, IFunctionExecutor executor, IExtensionRegistry extensions, SingletonManager singletonManager, TraceWriter trace) { if (typeLocator == null) { throw new ArgumentNullException("typeLocator"); } if (triggerBindingProvider == null) { throw new ArgumentNullException("triggerBindingProvider"); } if (bindingProvider == null) { throw new ArgumentNullException("bindingProvider"); } if (activator == null) { throw new ArgumentNullException("activator"); } if (executor == null) { throw new ArgumentNullException("executor"); } if (extensions == null) { throw new ArgumentNullException("extensions"); } if (singletonManager == null) { throw new ArgumentNullException("singletonManager"); } if (trace == null) { throw new ArgumentNullException("trace"); } _typeLocator = typeLocator; _triggerBindingProvider = triggerBindingProvider; _bindingProvider = bindingProvider; _activator = activator; _executor = executor; _extensions = extensions; _singletonManager = singletonManager; _trace = trace; }
public Service(Logger logger, ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IJobActivator jobActivator, IEnumerable<IJobConfiguration> jobsConfig, WcfServiceHostFactory serviceHostFactory) { _logger = logger; _schedulerFactory = schedulerFactory; _jobFactory = jobFactory; _jobActivator = jobActivator; _jobsConfig = jobsConfig; _serviceHostFactory = serviceHostFactory; ServiceName = Program.ServiceName; }
public MessageProcessor(IJobActivator jobActivator, ISerializer serializer, ILogger logger, RepositoryFactory factory) { if (serializer == null) throw new ArgumentNullException(nameof(serializer)); if (jobActivator == null) throw new ArgumentNullException(nameof(jobActivator)); _serializer = serializer; _jobActivator = jobActivator; Repository = factory.Create(); Service = new MessengerService(logger, factory); Logger = logger; Canceled = false; }
public async Task Trigger_IfClassConstructorHasDependencies_CanUseCustomJobActivator() { // Arrange const string expectedResult = "abc"; Mock <IFactory <string> > resultFactoryMock = new Mock <IFactory <string> >(MockBehavior.Strict); resultFactoryMock.Setup(f => f.Create()).Returns(expectedResult); IFactory <string> resultFactory = resultFactoryMock.Object; Mock <IJobActivator> activatorMock = new Mock <IJobActivator>(MockBehavior.Strict); activatorMock.Setup(a => a.CreateInstance <InstanceCustomActivatorProgram>()) .Returns(() => new InstanceCustomActivatorProgram(resultFactory)); IJobActivator activator = activatorMock.Object; CloudQueueMessage message = new CloudQueueMessage("ignore"); var account = new FakeStorageAccount(); await account.AddQueueMessageAsync(message, QueueName); IHost host = new HostBuilder() .ConfigureDefaultTestHost <InstanceCustomActivatorProgram>(builder => { builder.UseStorage(account); }, null, activator) .Build(); // Act var jobHost = host.GetJobHost <InstanceCustomActivatorProgram>(); Assert.NotNull(jobHost); var result = await jobHost.RunTriggerAsync <string>(InstanceCustomActivatorProgram.TaskSource); // Assert Assert.Same(expectedResult, result); }
public static FunctionIndexer Create(CloudStorageAccount account = null, INameResolver nameResolver = null, IExtensionRegistry extensionRegistry = null, ILoggerFactory loggerFactory = null) { IHost host = new HostBuilder() .ConfigureDefaultTestHost(b => { b.UseHostId("testhost") .AddAzureStorage(); }) .ConfigureServices(services => { services.AddSingleton <StorageAccountProvider>(new FakeStorageAccountProvider()); if (nameResolver != null) { services.AddSingleton <INameResolver>(nameResolver); } if (extensionRegistry != null) { services.AddSingleton <IExtensionRegistry>(extensionRegistry); } }) .Build(); ITriggerBindingProvider triggerBindingProvider = host.Services.GetService <ITriggerBindingProvider>(); IBindingProvider bindingProvider = host.Services.GetService <CompositeBindingProvider>(); IJobActivator activator = host.Services.GetService <IJobActivator>(); extensionRegistry = host.Services.GetService <IExtensionRegistry>(); SingletonManager singletonManager = host.Services.GetService <SingletonManager>(); IFunctionExecutor executor = host.Services.GetService <IFunctionExecutor>(); // TODO: This should be using DI internally and not be so complicated to construct return(new FunctionIndexer(triggerBindingProvider, bindingProvider, activator, executor, singletonManager, loggerFactory)); }
public object Perform(IJobActivator activator) { if (activator == null) throw new ArgumentNullException("activator"); object instance = null; object result; try { if (!Method.IsStatic) { instance = Activate(activator); } var deserializedArguments = DeserializeArguments(); result = InvokeMethod(instance, deserializedArguments); } finally { Dispose(instance); } return result; }
public FunctionIndexer(ITriggerBindingProvider triggerBindingProvider, IBindingProvider bindingProvider, IJobActivator activator) { if (triggerBindingProvider == null) { throw new ArgumentNullException("triggerBindingProvider"); } if (bindingProvider == null) { throw new ArgumentNullException("bindingProvider"); } if (activator == null) { throw new ArgumentNullException("activator"); } _triggerBindingProvider = triggerBindingProvider; _bindingProvider = bindingProvider; _activator = activator; Type serviceBusIndexerType = ServiceBusExtensionTypeLoader.Get("Microsoft.Azure.WebJobs.ServiceBus.ServiceBusIndexer"); if (serviceBusIndexerType != null) { MethodInfo serviceBusIndexerMethod = serviceBusIndexerType.GetMethod("HasSdkAttribute", new Type[] { typeof(MethodInfo) }); Debug.Assert(serviceBusIndexerMethod != null); _hasServiceBusAttribute = (Func <MethodInfo, bool>)serviceBusIndexerMethod.CreateDelegate( typeof(Func <MethodInfo, bool>)); } else { _hasServiceBusAttribute = _hasServiceBusAttributeDefault; } }
public static FunctionIndexer Create(CloudStorageAccount account = null, INameResolver nameResolver = null, IExtensionRegistry extensionRegistry = null, ILoggerFactory loggerFactory = null) { IStorageAccountProvider storageAccountProvider = GetStorageAccountProvider(account); var config = TestHelpers.NewConfig(storageAccountProvider, nameResolver, extensionRegistry); var services = config.CreateStaticServices(); ITriggerBindingProvider triggerBindingProvider = services.GetService <ITriggerBindingProvider>(); IBindingProvider bindingProvider = services.GetService <IBindingProvider>(); IJobActivator activator = services.GetService <IJobActivator>(); extensionRegistry = services.GetService <IExtensionRegistry>(); SingletonManager singletonManager = new SingletonManager(); IWebJobsExceptionHandler exceptionHandler = new WebJobsExceptionHandler(); IFunctionOutputLoggerProvider outputLoggerProvider = new NullFunctionOutputLoggerProvider(); IFunctionOutputLogger outputLogger = outputLoggerProvider.GetAsync(CancellationToken.None).Result; IFunctionExecutor executor = new FunctionExecutor(new NullFunctionInstanceLogger(), outputLogger, exceptionHandler, loggerFactory: loggerFactory); return(new FunctionIndexer(triggerBindingProvider, bindingProvider, DefaultJobActivator.Instance, executor, extensionRegistry, singletonManager, loggerFactory)); }
public void SetJobActivator(IJobActivator jobActivator) { JobActivator = jobActivator; Logger.Debug($"BackgroundJobManager: JobActivator:{jobActivator.GetType().FullName} is registered."); }
public static TResult RunTrigger <TResult>(IStorageAccount account, Type programType, Action <TaskCompletionSource <TResult> > setTaskSource, IJobActivator activator, IEnumerable <string> ignoreFailureFunctions) { // Arrange TaskCompletionSource <TResult> taskSource = new TaskCompletionSource <TResult>(); IServiceProvider serviceProvider = CreateServiceProviderForManualCompletion <TResult>(account, programType, activator, taskSource, ignoreFailureFunctions); Task <TResult> task = taskSource.Task; setTaskSource.Invoke(taskSource); try { // Act & Assert return(RunTrigger <TResult>(serviceProvider, task)); } finally { setTaskSource.Invoke(null); } }
private static IFunctionInvoker CreateGeneric <TReflected>(MethodInfo method, IJobActivator activator) { Debug.Assert(method != null); List <string> parameterNames = method.GetParameters().Select(p => p.Name).ToList(); IMethodInvoker <TReflected> methodInvoker = MethodInvokerFactory.Create <TReflected>(method); IFactory <TReflected> instanceFactory = CreateInstanceFactory <TReflected>(method, activator); return(new FunctionInvoker <TReflected>(parameterNames, instanceFactory, methodInvoker)); }
public HostListenerFactory(IEnumerable <IFunctionDefinition> functionDefinitions, SingletonManager singletonManager, IJobActivator activator, INameResolver nameResolver, TraceWriter trace) { _functionDefinitions = functionDefinitions; _singletonManager = singletonManager; _activator = activator; _nameResolver = nameResolver; _trace = trace; }
public static TResult RunTrigger <TResult>(IStorageAccount account, Type programType, IJobActivator activator, Action <TaskCompletionSource <TResult> > setTaskSource) { return(RunTrigger <TResult>(account, programType, setTaskSource, activator, ignoreFailureFunctions: null)); }
internal static bool IsDisabledByProvider(Type providerType, MethodInfo jobFunction, IJobActivator activator) { MethodInfo methodInfo = providerType.GetMethod(IsDisabledFunctionName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(MethodInfo) }, null); if (methodInfo == null) { methodInfo = providerType.GetMethod(IsDisabledFunctionName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(MethodInfo) }, null); } if (methodInfo == null || methodInfo.ReturnType != typeof(bool)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' must declare a method 'IsDisabled' returning bool and taking a single parameter of Type MethodInfo.", providerType.Name)); } if (methodInfo.IsStatic) { return (bool)methodInfo.Invoke(null, new object[] { jobFunction }); } else { MethodInfo createMethod = JobActivatorCreateMethod.MakeGenericMethod(providerType); object instance = createMethod.Invoke(activator, null); return (bool)methodInfo.Invoke(instance, new object[] { jobFunction }); } }
private static JobHostConfiguration CreateConfiguration <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger, IExtensionRegistry extensions = null) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IHostIdProvider hostIdProvider = new FakeHostIdProvider(); IWebJobsExceptionHandler exceptionHandler = new TaskBackgroundExceptionHandler <TResult>(taskSource); return(TestHelpers.NewConfig( programType, new FakeQueueConfiguration(storageAccountProvider), storageAccountProvider, extensionTypeLocator, activator, extensions, exceptionHandler, new NullFunctionInstanceLoggerProvider(functionInstanceLogger), new NullHostInstanceLoggerProvider(), new NullFunctionOutputLoggerProvider() )); }
public HostListenerFactory(IEnumerable <IFunctionDefinition> functionDefinitions, SingletonManager singletonManager, IJobActivator activator, INameResolver nameResolver, ILoggerFactory loggerFactory, bool allowPartialHostStartup = false) { _functionDefinitions = functionDefinitions; _singletonManager = singletonManager; _activator = activator; _nameResolver = nameResolver; _loggerFactory = loggerFactory; _logger = _loggerFactory?.CreateLogger(LogCategories.Startup); _allowPartialHostStartup = allowPartialHostStartup; }
private static TResult RunTrigger <TResult>(IStorageAccount account, Type programType, Action <TaskCompletionSource <TResult> > setTaskSource, IJobActivator activator) { return(FunctionalTest.RunTrigger <TResult>(account, programType, activator, setTaskSource)); }
private static IServiceProvider CreateServiceProvider <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IServiceBusAccountProvider serviceBusAccountProvider = new NullServiceBusAccountProvider(); IHostIdProvider hostIdProvider = new FakeHostIdProvider(); INameResolver nameResolver = null; IQueueConfiguration queueConfiguration = new FakeQueueConfiguration(); IBackgroundExceptionDispatcher backgroundExceptionDispatcher = new TaskBackgroundExceptionDispatcher <TResult>(taskSource); ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, serviceBusAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, TextWriter.Null); IBindingProvider bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, serviceBusAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor); IJobHostContextFactory contextFactory = new FakeJobHostContextFactory { FunctionIndexProvider = new FunctionIndexProvider(new FakeTypeLocator(programType), triggerBindingProvider, bindingProvider, activator), StorageAccountProvider = storageAccountProvider, ServiceBusAccountProvider = serviceBusAccountProvider, BackgroundExceptionDispatcher = backgroundExceptionDispatcher, BindingProvider = bindingProvider, ConsoleProvider = new NullConsoleProvider(), HostInstanceLoggerProvider = new NullHostInstanceLoggerProvider(), FunctionInstanceLoggerProvider = new FakeFunctionInstanceLoggerProvider(functionInstanceLogger), FunctionOutputLoggerProvider = new NullFunctionOutputLoggerProvider(), HostIdProvider = hostIdProvider, QueueConfiguration = new FakeQueueConfiguration() }; return(new FakeServiceProvider { ContextFactory = contextFactory }); }
public FunctionIndexer(ITriggerBindingProvider triggerBindingProvider, IBindingProvider bindingProvider, IJobActivator activator, IFunctionExecutor executor, IExtensionRegistry extensions, SingletonManager singletonManager, TraceWriter trace) { if (triggerBindingProvider == null) { throw new ArgumentNullException("triggerBindingProvider"); } if (bindingProvider == null) { throw new ArgumentNullException("bindingProvider"); } if (activator == null) { throw new ArgumentNullException("activator"); } if (executor == null) { throw new ArgumentNullException("executor"); } if (extensions == null) { throw new ArgumentNullException("extensions"); } if (singletonManager == null) { throw new ArgumentNullException("singletonManager"); } if (trace == null) { throw new ArgumentNullException("trace"); } _triggerBindingProvider = triggerBindingProvider; _bindingProvider = bindingProvider; _activator = activator; _executor = executor; _singletonManager = singletonManager; _jobAttributeAssemblies = GetJobAttributeAssemblies(extensions); _trace = trace; }
private static ActivatorInstanceFactory<TReflected> CreateProductUnderTest<TReflected>(IJobActivator activator) { return new ActivatorInstanceFactory<TReflected>(activator); }
public Service(Logger logger, ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IJobActivator jobActivator, IEnumerable <IJobConfiguration> jobsConfig, WcfServiceHostFactory serviceHostFactory) { _logger = logger; _schedulerFactory = schedulerFactory; _jobFactory = jobFactory; _jobActivator = jobActivator; _jobsConfig = jobsConfig; _serviceHostFactory = serviceHostFactory; ServiceName = Program.ServiceName; }
private static void ListenQueue(string queueName, IJobActivator jobActivator, Logger logger, ConcurrentHashSet <InWorkMessage> inworkMessages, CancellationToken cancellationToken) { if (!MessageQueue.Exists(queueName)) { throw new InvalidOperationException(string.Format("Очередь {0} отсутствует.", queueName)); } var mq = new MessageQueue(queueName); while (true) { try { using (var messageQueueTransaction = new MessageQueueTransaction()) { messageQueueTransaction.Begin(); var mes = mq.Receive(messageQueueTransaction); if (mes == null) { logger.Error("Получено пустое сообщение"); continue; } if (cancellationToken.IsCancellationRequested) { logger.Info("Операция отменена"); return; } mes.Formatter = new XmlMessageFormatter(new[] { typeof(MessageWrapper) }); var inWorkMessage = new InWorkMessage { Job = (MessageWrapper)mes.Body, QueueName = queueName, Label = mes.Label }; if (!inworkMessages.TryAdd(inWorkMessage)) { continue; } if (inWorkMessage.Job.RetryCount == 0) { logger.Info("Запущена задача {0}", inWorkMessage.Label); } else { logger.Info("Запущена задача {0}. Повторная попытка {1}", inWorkMessage.Label, inWorkMessage.Job.RetryCount); } var serializedjob = JobHelper.FromJson <SerializedJob>(inWorkMessage.Job.SerializedJob); var job = serializedjob.Deserialize(); //Отправляем задачу в работу и добавляем обработчик который в случае ошибки или отмены задачи вернет сообщение в очередь. //Если задача завершилась успешно, проставляем флаг об этом. Task.Factory.StartNew(() => job.Perform(jobActivator, cancellationToken), cancellationToken) .ContinueWith(t => { if (t.Exception != null) { t.Exception.Handle(ex => { if (ex.GetType() == typeof(JobFailedException)) { logger.Info("При выполнении задачи {0} возникла ошибка.", inWorkMessage.Label); logger.Error(ex.GetAllInnerExceptionMessagesAndTrace()); Thread.Sleep(60000); ReturnMessageToQueue(inWorkMessage, inworkMessages, cancellationToken); return(true); } logger.Fatal(ex.GetAllInnerExceptionMessagesAndTrace()); ReturnMessageToQueue(inWorkMessage, inworkMessages, cancellationToken); return(false); }); } else { logger.Info("Задача {0} завершилась успешно.", inWorkMessage.Label); inWorkMessage.CompleteMessage(); } }, TaskContinuationOptions.NotOnCanceled); messageQueueTransaction.Commit(); } } catch (Exception e) { logger.Fatal(e.GetAllInnerExceptionMessagesAndTrace()); //inworkMessages.CompleteAdding(); throw; } } }
private static IJobInstanceFactory <TReflected> CreateInstanceFactory <TReflected>(MethodInfo method, IJobActivator jobActivator) { Debug.Assert(method != null); if (method.IsStatic) { return(NullInstanceFactory <TReflected> .Instance); } else { return(new ActivatorInstanceFactory <TReflected>(jobActivator)); } }
private static void ListenQueue(string queueName, IJobActivator jobActivator, Logger logger, ConcurrentHashSet<InWorkMessage> inworkMessages, CancellationToken cancellationToken) { if (!MessageQueue.Exists(queueName)) { throw new InvalidOperationException(string.Format("Очередь {0} отсутствует.", queueName)); } var mq = new MessageQueue(queueName); while (true) { try { using (var messageQueueTransaction = new MessageQueueTransaction()) { messageQueueTransaction.Begin(); var mes = mq.Receive(messageQueueTransaction); if (mes == null) { logger.Error("Получено пустое сообщение"); continue; } if (cancellationToken.IsCancellationRequested) { logger.Info("Операция отменена"); return; } mes.Formatter = new XmlMessageFormatter(new[] {typeof(MessageWrapper)}); var inWorkMessage = new InWorkMessage { Job = (MessageWrapper)mes.Body, QueueName = queueName, Label = mes.Label}; if(!inworkMessages.TryAdd(inWorkMessage)) continue; if (inWorkMessage.Job.RetryCount==0) logger.Info("Запущена задача {0}", inWorkMessage.Label); else logger.Info("Запущена задача {0}. Повторная попытка {1}", inWorkMessage.Label, inWorkMessage.Job.RetryCount); var serializedjob = JobHelper.FromJson<SerializedJob>(inWorkMessage.Job.SerializedJob); var job = serializedjob.Deserialize(); //Отправляем задачу в работу и добавляем обработчик который в случае ошибки или отмены задачи вернет сообщение в очередь. //Если задача завершилась успешно, проставляем флаг об этом. Task.Factory.StartNew(() => job.Perform(jobActivator, cancellationToken), cancellationToken) .ContinueWith(t => { if (t.Exception != null) { t.Exception.Handle(ex => { if (ex.GetType() == typeof (JobFailedException)) { logger.Info("При выполнении задачи {0} возникла ошибка.", inWorkMessage.Label); logger.Error(ex.GetAllInnerExceptionMessagesAndTrace()); Thread.Sleep(60000); ReturnMessageToQueue(inWorkMessage, inworkMessages, cancellationToken); return true; } logger.Fatal(ex.GetAllInnerExceptionMessagesAndTrace()); ReturnMessageToQueue(inWorkMessage, inworkMessages, cancellationToken); return false; }); } else { logger.Info("Задача {0} завершилась успешно.", inWorkMessage.Label); inWorkMessage.CompleteMessage(); } }, TaskContinuationOptions.NotOnCanceled); messageQueueTransaction.Commit(); } } catch (Exception e) { logger.Fatal(e.GetAllInnerExceptionMessagesAndTrace()); //inworkMessages.CompleteAdding(); throw; } } }
// Do the full runtime intitialization. This includes static initialization. // This mainly means: // - indexing the functions // - spinning up the listeners (so connecting to the services) public static async Task <JobHostContext> CreateJobHostContextAsync( this JobHostConfiguration config, ServiceProviderWrapper services, // Results from first phase JobHost host, CancellationToken shutdownToken, CancellationToken cancellationToken) { FunctionExecutor functionExecutor = services.GetService <FunctionExecutor>(); IFunctionIndexProvider functionIndexProvider = services.GetService <IFunctionIndexProvider>(); ITriggerBindingProvider triggerBindingProvider = services.GetService <ITriggerBindingProvider>(); IBindingProvider bindingProvider = services.GetService <IBindingProvider>(); SingletonManager singletonManager = services.GetService <SingletonManager>(); IJobActivator activator = services.GetService <IJobActivator>(); IHostIdProvider hostIdProvider = services.GetService <IHostIdProvider>(); INameResolver nameResolver = services.GetService <INameResolver>(); IExtensionRegistry extensions = services.GetExtensions(); IStorageAccountProvider storageAccountProvider = services.GetService <IStorageAccountProvider>(); ILoggerFactory loggerFactory = services.GetService <ILoggerFactory>(); IFunctionResultAggregatorFactory aggregatorFactory = services.GetService <IFunctionResultAggregatorFactory>(); IAsyncCollector <FunctionInstanceLogEntry> functionEventCollector = null; // Create the aggregator if all the pieces are configured IAsyncCollector <FunctionInstanceLogEntry> aggregator = null; if (loggerFactory != null && aggregatorFactory != null && config.Aggregator.IsEnabled) { aggregator = aggregatorFactory.Create(config.Aggregator.BatchSize, config.Aggregator.FlushTimeout, loggerFactory); } IQueueConfiguration queueConfiguration = services.GetService <IQueueConfiguration>(); var blobsConfiguration = config.Blobs; TraceWriter trace = services.GetService <TraceWriter>(); IAsyncCollector <FunctionInstanceLogEntry> registeredFunctionEventCollector = services.GetService <IAsyncCollector <FunctionInstanceLogEntry> >(); if (registeredFunctionEventCollector != null && aggregator != null) { // If there are both an aggregator and a registered FunctionEventCollector, wrap them in a composite functionEventCollector = new CompositeFunctionEventCollector(new[] { registeredFunctionEventCollector, aggregator }); } else { // Otherwise, take whichever one is null (or use null if both are) functionEventCollector = aggregator ?? registeredFunctionEventCollector; } IWebJobsExceptionHandler exceptionHandler = services.GetService <IWebJobsExceptionHandler>(); if (exceptionHandler != null) { exceptionHandler.Initialize(host); } bool hasFastTableHook = services.GetService <IAsyncCollector <FunctionInstanceLogEntry> >() != null; bool noDashboardStorage = config.DashboardConnectionString == null; // Only testing will override these interfaces. IHostInstanceLoggerProvider hostInstanceLoggerProvider = services.GetService <IHostInstanceLoggerProvider>(); IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = services.GetService <IFunctionInstanceLoggerProvider>(); IFunctionOutputLoggerProvider functionOutputLoggerProvider = services.GetService <IFunctionOutputLoggerProvider>(); if (hostInstanceLoggerProvider == null && functionInstanceLoggerProvider == null && functionOutputLoggerProvider == null) { if (hasFastTableHook && noDashboardStorage) { var loggerProvider = new FastTableLoggerProvider(trace); hostInstanceLoggerProvider = loggerProvider; functionInstanceLoggerProvider = loggerProvider; functionOutputLoggerProvider = loggerProvider; } else { var loggerProvider = new DefaultLoggerProvider(storageAccountProvider, trace); hostInstanceLoggerProvider = loggerProvider; functionInstanceLoggerProvider = loggerProvider; functionOutputLoggerProvider = loggerProvider; } } using (CancellationTokenSource combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, shutdownToken)) { CancellationToken combinedCancellationToken = combinedCancellationSource.Token; await WriteSiteExtensionManifestAsync(combinedCancellationToken); IStorageAccount dashboardAccount = await storageAccountProvider.GetDashboardAccountAsync(combinedCancellationToken); IHostInstanceLogger hostInstanceLogger = await hostInstanceLoggerProvider.GetAsync(combinedCancellationToken); IFunctionInstanceLogger functionInstanceLogger = await functionInstanceLoggerProvider.GetAsync(combinedCancellationToken); IFunctionOutputLogger functionOutputLogger = await functionOutputLoggerProvider.GetAsync(combinedCancellationToken); if (functionExecutor == null) { var extensionRegistry = config.GetService <IExtensionRegistry>(); var globalFunctionFilters = extensionRegistry.GetFunctionFilters(); functionExecutor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, exceptionHandler, trace, functionEventCollector, loggerFactory, globalFunctionFilters); services.AddService(functionExecutor); } if (functionIndexProvider == null) { functionIndexProvider = new FunctionIndexProvider( services.GetService <ITypeLocator>(), triggerBindingProvider, bindingProvider, activator, functionExecutor, extensions, singletonManager, trace, loggerFactory); // Important to set this so that the func we passed to DynamicHostIdProvider can pick it up. services.AddService <IFunctionIndexProvider>(functionIndexProvider); } IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken); IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll(), singletonManager, activator, nameResolver, trace, loggerFactory); IFunctionExecutor hostCallExecutor; IListener listener; HostOutputMessage hostOutputMessage; string hostId = await hostIdProvider.GetHostIdAsync(cancellationToken); if (string.Compare(config.HostId, hostId, StringComparison.OrdinalIgnoreCase) != 0) { // if this isn't a static host ID, provide the HostId on the config // so it is accessible config.HostId = hostId; } if (dashboardAccount == null) { hostCallExecutor = new ShutdownFunctionExecutor(shutdownToken, functionExecutor); IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory); IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener); listener = shutdownListener; hostOutputMessage = new DataOnlyHostOutputMessage(); } else { string sharedQueueName = HostQueueNames.GetHostQueueName(hostId); IStorageQueueClient dashboardQueueClient = dashboardAccount.CreateQueueClient(); IStorageQueue sharedQueue = dashboardQueueClient.GetQueueReference(sharedQueueName); IListenerFactory sharedQueueListenerFactory = new HostMessageListenerFactory(sharedQueue, queueConfiguration, exceptionHandler, trace, loggerFactory, functions, functionInstanceLogger, functionExecutor); Guid hostInstanceId = Guid.NewGuid(); string instanceQueueName = HostQueueNames.GetHostQueueName(hostInstanceId.ToString("N")); IStorageQueue instanceQueue = dashboardQueueClient.GetQueueReference(instanceQueueName); IListenerFactory instanceQueueListenerFactory = new HostMessageListenerFactory(instanceQueue, queueConfiguration, exceptionHandler, trace, loggerFactory, functions, functionInstanceLogger, functionExecutor); HeartbeatDescriptor heartbeatDescriptor = new HeartbeatDescriptor { SharedContainerName = HostContainerNames.Hosts, SharedDirectoryName = HostDirectoryNames.Heartbeats + "/" + hostId, InstanceBlobName = hostInstanceId.ToString("N"), ExpirationInSeconds = (int)HeartbeatIntervals.ExpirationInterval.TotalSeconds }; IStorageBlockBlob blob = dashboardAccount.CreateBlobClient() .GetContainerReference(heartbeatDescriptor.SharedContainerName) .GetBlockBlobReference(heartbeatDescriptor.SharedDirectoryName + "/" + heartbeatDescriptor.InstanceBlobName); IRecurrentCommand heartbeatCommand = new UpdateHostHeartbeatCommand(new HeartbeatCommand(blob)); IEnumerable <MethodInfo> indexedMethods = functions.ReadAllMethods(); Assembly hostAssembly = GetHostAssembly(indexedMethods); string displayName = hostAssembly != null?AssemblyNameCache.GetName(hostAssembly).Name : "Unknown"; hostOutputMessage = new DataOnlyHostOutputMessage { HostInstanceId = hostInstanceId, HostDisplayName = displayName, SharedQueueName = sharedQueueName, InstanceQueueName = instanceQueueName, Heartbeat = heartbeatDescriptor, WebJobRunIdentifier = WebJobRunIdentifier.Current }; hostCallExecutor = CreateHostCallExecutor(instanceQueueListenerFactory, heartbeatCommand, exceptionHandler, shutdownToken, functionExecutor); IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory, sharedQueueListenerFactory, instanceQueueListenerFactory); listener = CreateHostListener(hostListenerFactory, heartbeatCommand, exceptionHandler, shutdownToken); // Publish this to Azure logging account so that a web dashboard can see it. await LogHostStartedAsync(functions, hostOutputMessage, hostInstanceLogger, combinedCancellationToken); } functionExecutor.HostOutputMessage = hostOutputMessage; IEnumerable <FunctionDescriptor> descriptors = functions.ReadAllDescriptors(); int descriptorsCount = descriptors.Count(); ILogger startupLogger = loggerFactory?.CreateLogger(LogCategories.Startup); if (config.UsingDevelopmentSettings) { string msg = "Development settings applied"; trace.Verbose(msg); startupLogger?.LogDebug(msg); } if (descriptorsCount == 0) { string msg = string.Format("No job functions found. Try making your job classes and methods public. {0}", Constants.ExtensionInitializationMessage); trace.Warning(msg, Host.TraceSource.Indexing); startupLogger?.LogWarning(msg); } else { StringBuilder functionsTrace = new StringBuilder(); functionsTrace.AppendLine("Found the following functions:"); foreach (FunctionDescriptor descriptor in descriptors) { functionsTrace.AppendLine(descriptor.FullName); } string msg = functionsTrace.ToString(); trace.Info(msg, Host.TraceSource.Indexing); startupLogger?.LogInformation(msg); } return(new JobHostContext( functions, hostCallExecutor, listener, trace, functionEventCollector, loggerFactory)); } }
public static IHostBuilder ConfigureDefaultTestHost <TProgram>(this IHostBuilder builder, Action <IWebJobsBuilder> configureWebJobs, INameResolver nameResolver = null, IJobActivator activator = null) { return(builder.ConfigureDefaultTestHost(configureWebJobs, typeof(TProgram)) .ConfigureServices(services => { services.AddSingleton <IJobHost, JobHost <TProgram> >(); if (nameResolver != null) { services.AddSingleton <INameResolver>(nameResolver); } if (activator != null) { services.AddSingleton <IJobActivator>(activator); } })); }
public HostListenerFactory(IEnumerable <IFunctionDefinition> functionDefinitions, SingletonManager singletonManager, IJobActivator activator, INameResolver nameResolver, TraceWriter trace, ILoggerFactory loggerFactory) { _functionDefinitions = functionDefinitions; _singletonManager = singletonManager; _activator = activator; _nameResolver = nameResolver; _trace = trace; _loggerFactory = loggerFactory; _logger = _loggerFactory?.CreateLogger(LogCategories.Startup); }
private void Activate(IJobActivator activator, object[] deserializedArguments) { activator.ActivateJob(Type, Method, deserializedArguments); }
public static async Task <JobHostContext> CreateAndLogHostStartedAsync( JobHost host, IStorageAccountProvider storageAccountProvider, IQueueConfiguration queueConfiguration, ITypeLocator typeLocator, IJobActivator activator, INameResolver nameResolver, IConsoleProvider consoleProvider, JobHostConfiguration config, CancellationToken shutdownToken, CancellationToken cancellationToken, IHostIdProvider hostIdProvider = null, FunctionExecutor functionExecutor = null, IFunctionIndexProvider functionIndexProvider = null, IBindingProvider bindingProvider = null, IHostInstanceLoggerProvider hostInstanceLogerProvider = null, IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = null, IFunctionOutputLoggerProvider functionOutputLoggerProvider = null, IBackgroundExceptionDispatcher backgroundExceptionDispatcher = null, SingletonManager singletonManager = null) { if (hostIdProvider == null) { hostIdProvider = new DynamicHostIdProvider(storageAccountProvider, () => functionIndexProvider); } IExtensionTypeLocator extensionTypeLocator = new ExtensionTypeLocator(typeLocator); if (backgroundExceptionDispatcher == null) { backgroundExceptionDispatcher = BackgroundExceptionDispatcher.Instance; } ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); // Create a wrapper TraceWriter that delegates to both the user // TraceWriter specified on Config (if present), as well as to Console TraceWriter trace = new ConsoleTraceWriter(config.Tracing, consoleProvider.Out); // Register system services with the service container config.AddService <INameResolver>(nameResolver); ExtensionConfigContext context = new ExtensionConfigContext { Config = config, Trace = trace, Host = host }; InvokeExtensionConfigProviders(context); IExtensionRegistry extensions = config.GetExtensions(); ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, trace); if (bindingProvider == null) { bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions); } DefaultLoggerProvider loggerProvider = new DefaultLoggerProvider(storageAccountProvider, trace); if (singletonManager == null) { singletonManager = new SingletonManager(storageAccountProvider, backgroundExceptionDispatcher, config.Singleton, trace, config.NameResolver); } using (CancellationTokenSource combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, shutdownToken)) { CancellationToken combinedCancellationToken = combinedCancellationSource.Token; await WriteSiteExtensionManifestAsync(combinedCancellationToken); IStorageAccount dashboardAccount = await storageAccountProvider.GetDashboardAccountAsync(combinedCancellationToken); IHostInstanceLogger hostInstanceLogger = null; if (hostInstanceLogerProvider != null) { hostInstanceLogger = await hostInstanceLogerProvider.GetAsync(combinedCancellationToken); } else { hostInstanceLogger = await((IHostInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken); } IFunctionInstanceLogger functionInstanceLogger = null; if (functionInstanceLoggerProvider != null) { functionInstanceLogger = await functionInstanceLoggerProvider.GetAsync(combinedCancellationToken); } else { functionInstanceLogger = (IFunctionInstanceLogger)(await((IFunctionInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken)); } IFunctionOutputLogger functionOutputLogger = null; if (functionOutputLoggerProvider != null) { functionOutputLogger = await functionOutputLoggerProvider.GetAsync(combinedCancellationToken); } else { functionOutputLogger = (IFunctionOutputLogger)(await((IFunctionOutputLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken)); } if (functionExecutor == null) { functionExecutor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher, trace, config.FunctionTimeout); } if (functionIndexProvider == null) { functionIndexProvider = new FunctionIndexProvider(typeLocator, triggerBindingProvider, bindingProvider, activator, functionExecutor, extensions, singletonManager); } IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken); IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll(), singletonManager, activator, nameResolver, trace); IFunctionExecutor hostCallExecutor; IListener listener; HostOutputMessage hostOutputMessage; if (dashboardAccount != null) { string hostId = await hostIdProvider.GetHostIdAsync(cancellationToken); string sharedQueueName = HostQueueNames.GetHostQueueName(hostId); IStorageQueueClient dashboardQueueClient = dashboardAccount.CreateQueueClient(); IStorageQueue sharedQueue = dashboardQueueClient.GetQueueReference(sharedQueueName); IListenerFactory sharedQueueListenerFactory = new HostMessageListenerFactory(sharedQueue, queueConfiguration, backgroundExceptionDispatcher, trace, functions, functionInstanceLogger, functionExecutor); Guid hostInstanceId = Guid.NewGuid(); string instanceQueueName = HostQueueNames.GetHostQueueName(hostInstanceId.ToString("N")); IStorageQueue instanceQueue = dashboardQueueClient.GetQueueReference(instanceQueueName); IListenerFactory instanceQueueListenerFactory = new HostMessageListenerFactory(instanceQueue, queueConfiguration, backgroundExceptionDispatcher, trace, functions, functionInstanceLogger, functionExecutor); HeartbeatDescriptor heartbeatDescriptor = new HeartbeatDescriptor { SharedContainerName = HostContainerNames.Hosts, SharedDirectoryName = HostDirectoryNames.Heartbeats + "/" + hostId, InstanceBlobName = hostInstanceId.ToString("N"), ExpirationInSeconds = (int)HeartbeatIntervals.ExpirationInterval.TotalSeconds }; IStorageBlockBlob blob = dashboardAccount.CreateBlobClient() .GetContainerReference(heartbeatDescriptor.SharedContainerName) .GetBlockBlobReference(heartbeatDescriptor.SharedDirectoryName + "/" + heartbeatDescriptor.InstanceBlobName); IRecurrentCommand heartbeatCommand = new UpdateHostHeartbeatCommand(new HeartbeatCommand(blob)); IEnumerable <MethodInfo> indexedMethods = functions.ReadAllMethods(); Assembly hostAssembly = GetHostAssembly(indexedMethods); string displayName = hostAssembly != null?hostAssembly.GetName().Name : "Unknown"; hostOutputMessage = new DataOnlyHostOutputMessage { HostInstanceId = hostInstanceId, HostDisplayName = displayName, SharedQueueName = sharedQueueName, InstanceQueueName = instanceQueueName, Heartbeat = heartbeatDescriptor, WebJobRunIdentifier = WebJobRunIdentifier.Current }; hostCallExecutor = CreateHostCallExecutor(instanceQueueListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken, functionExecutor); IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory, sharedQueueListenerFactory, instanceQueueListenerFactory); listener = CreateHostListener(hostListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken); // Publish this to Azure logging account so that a web dashboard can see it. await LogHostStartedAsync(functions, hostOutputMessage, hostInstanceLogger, combinedCancellationToken); } else { hostCallExecutor = new ShutdownFunctionExecutor(shutdownToken, functionExecutor); IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory); IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener); listener = shutdownListener; hostOutputMessage = new DataOnlyHostOutputMessage(); } functionExecutor.HostOutputMessage = hostOutputMessage; IEnumerable <FunctionDescriptor> descriptors = functions.ReadAllDescriptors(); int descriptorsCount = descriptors.Count(); if (descriptorsCount == 0) { trace.Warning(string.Format("No job functions found. Try making your job classes and methods public. {0}", Constants.ExtensionInitializationMessage), TraceSource.Indexing); } else { StringBuilder functionsTrace = new StringBuilder(); functionsTrace.AppendLine("Found the following functions:"); foreach (FunctionDescriptor descriptor in descriptors) { functionsTrace.AppendLine(descriptor.FullName); } trace.Info(functionsTrace.ToString(), TraceSource.Indexing); } return(new JobHostContext(functions, hostCallExecutor, listener, trace)); } }
internal static bool IsDisabled(MethodInfo method, INameResolver nameResolver, IJobActivator activator) { ParameterInfo triggerParameter = method.GetParameters().FirstOrDefault(); if (triggerParameter != null) { // look for the first DisableAttribute up the hierarchy DisableAttribute disableAttribute = TypeUtility.GetHierarchicalAttributeOrNull <DisableAttribute>(triggerParameter); if (disableAttribute != null) { if (!string.IsNullOrEmpty(disableAttribute.SettingName)) { return(IsDisabledBySetting(disableAttribute.SettingName, method, nameResolver)); } else if (disableAttribute.ProviderType != null) { // a custom provider Type has been specified return(IsDisabledByProvider(disableAttribute.ProviderType, method, activator)); } else { // the default constructor was used return(true); } } } return(false); }
private static IServiceProvider CreateServiceProvider <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger, IExtensionRegistry extensions = null) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IHostIdProvider hostIdProvider = new FakeHostIdProvider(); INameResolver nameResolver = null; IQueueConfiguration queueConfiguration = new FakeQueueConfiguration(storageAccountProvider); IBackgroundExceptionDispatcher backgroundExceptionDispatcher = new TaskBackgroundExceptionDispatcher <TResult>(taskSource); ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); if (extensions == null) { extensions = new DefaultExtensionRegistry(); } ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, TextWriter.Null); IBindingProvider bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions); IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = new NullFunctionInstanceLoggerProvider(); IFunctionOutputLoggerProvider functionOutputLoggerProvider = new NullFunctionOutputLoggerProvider(); Task <IFunctionOutputLogger> task = functionOutputLoggerProvider.GetAsync(CancellationToken.None); task.Wait(); IFunctionOutputLogger functionOutputLogger = task.Result; FunctionExecutor executor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher); ITypeLocator typeLocator = new FakeTypeLocator(programType); FunctionIndexProvider functionIndexProvider = new FunctionIndexProvider( typeLocator, triggerBindingProvider, bindingProvider, activator, executor, extensions); IJobHostContextFactory contextFactory = new FakeJobHostContextFactory { TypeLocator = typeLocator, FunctionIndexProvider = functionIndexProvider, StorageAccountProvider = storageAccountProvider, BackgroundExceptionDispatcher = backgroundExceptionDispatcher, BindingProvider = bindingProvider, ConsoleProvider = new NullConsoleProvider(), HostInstanceLoggerProvider = new NullHostInstanceLoggerProvider(), FunctionExecutor = executor, FunctionInstanceLoggerProvider = functionInstanceLoggerProvider, FunctionOutputLoggerProvider = functionOutputLoggerProvider, HostIdProvider = hostIdProvider, QueueConfiguration = queueConfiguration }; return(new FakeServiceProvider { ContextFactory = contextFactory }); }
public JobHostContextFactory(IStorageAccountProvider storageAccountProvider, IServiceBusAccountProvider serviceBusAccountProvider, ITypeLocator typeLocator, INameResolver nameResolver, IJobActivator activator, string hostId, IQueueConfiguration queueConfiguration, IConsoleProvider consoleProvider) { _storageAccountProvider = storageAccountProvider; _serviceBusAccountProvider = serviceBusAccountProvider; _typeLocator = typeLocator; _activator = activator; _nameResolver = nameResolver; _hostId = hostId; _queueConfiguration = queueConfiguration; _consoleProvider = consoleProvider; }
internal static bool IsDisabledByProvider(Type providerType, MethodInfo jobFunction, IJobActivator activator) { MethodInfo methodInfo = providerType.GetMethod(IsDisabledFunctionName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(MethodInfo) }, null); if (methodInfo == null) { methodInfo = providerType.GetMethod(IsDisabledFunctionName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(MethodInfo) }, null); } if (methodInfo == null || methodInfo.ReturnType != typeof(bool)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' must declare a method 'IsDisabled' returning bool and taking a single parameter of Type MethodInfo.", providerType.Name)); } if (methodInfo.IsStatic) { return((bool)methodInfo.Invoke(null, new object[] { jobFunction })); } else { MethodInfo createMethod = JobActivatorCreateMethod.MakeGenericMethod(providerType); object instance = createMethod.Invoke(activator, null); return((bool)methodInfo.Invoke(instance, new object[] { jobFunction })); } }
private object Activate(IJobActivator activator) { try { var instance = activator.ActivateJob(Type); if (instance == null) { throw new InvalidOperationException( String.Format("JobActivator returned NULL instance of the '{0}' type.", Type)); } return instance; } catch (Exception ex) { throw new Exception("An exception occurred during job activation.", ex); } }
internal static bool IsDisabled(MethodInfo method, INameResolver nameResolver, IJobActivator activator) { // First try to resolve disabled state by setting string settingName = string.Format(CultureInfo.InvariantCulture, "AzureWebJobs.{0}.Disabled", Utility.GetFunctionName(method)); if (ConfigurationUtility.IsSettingEnabled(settingName)) { return(true); } else { // Second try to resolve disabled state by attribute ParameterInfo triggerParameter = method.GetParameters().FirstOrDefault(); if (triggerParameter != null) { // look for the first DisableAttribute up the hierarchy DisableAttribute disableAttribute = TypeUtility.GetHierarchicalAttributeOrNull <DisableAttribute>(triggerParameter); if (disableAttribute != null) { if (!string.IsNullOrEmpty(disableAttribute.SettingName)) { return(IsDisabledBySetting(disableAttribute.SettingName, method, nameResolver)); } else if (disableAttribute.ProviderType != null) { // a custom provider Type has been specified return(IsDisabledByProvider(disableAttribute.ProviderType, method, activator)); } else { // the default constructor was used return(true); } } } return(false); } }
public FunctionInstanceServicesCatalog(IJobActivator innerActivator) { _instanceServices = new ConditionalWeakTable <IFunctionInstanceEx, IServiceProvider>(); _innerActivator = (IJobActivatorEx)innerActivator; }
public static async Task<JobHostContext> CreateAndLogHostStartedAsync( JobHost host, IStorageAccountProvider storageAccountProvider, IQueueConfiguration queueConfiguration, ITypeLocator typeLocator, IJobActivator activator, INameResolver nameResolver, IConsoleProvider consoleProvider, JobHostConfiguration config, CancellationToken shutdownToken, CancellationToken cancellationToken, IHostIdProvider hostIdProvider = null, FunctionExecutor functionExecutor = null, IFunctionIndexProvider functionIndexProvider = null, IBindingProvider bindingProvider = null, IHostInstanceLoggerProvider hostInstanceLogerProvider = null, IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = null, IFunctionOutputLoggerProvider functionOutputLoggerProvider = null, IBackgroundExceptionDispatcher backgroundExceptionDispatcher = null, SingletonManager singletonManager = null) { if (hostIdProvider == null) { hostIdProvider = new DynamicHostIdProvider(storageAccountProvider, () => functionIndexProvider); } IExtensionTypeLocator extensionTypeLocator = new ExtensionTypeLocator(typeLocator); if (backgroundExceptionDispatcher == null) { backgroundExceptionDispatcher = BackgroundExceptionDispatcher.Instance; } ContextAccessor<IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor<IMessageEnqueuedWatcher>(); ContextAccessor<IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor<IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); // Create a wrapper TraceWriter that delegates to both the user // TraceWriter specified on Config (if present), as well as to Console TraceWriter trace = new ConsoleTraceWriter(config.Tracing, consoleProvider.Out); // Register system services with the service container config.AddService<INameResolver>(nameResolver); ExtensionConfigContext context = new ExtensionConfigContext { Config = config, Trace = trace, Host = host }; InvokeExtensionConfigProviders(context); IExtensionRegistry extensions = config.GetExtensions(); ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, trace); if (bindingProvider == null) { bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions); } DefaultLoggerProvider loggerProvider = new DefaultLoggerProvider(storageAccountProvider, trace); if (singletonManager == null) { singletonManager = new SingletonManager(storageAccountProvider, backgroundExceptionDispatcher, config.Singleton, trace, config.NameResolver); } using (CancellationTokenSource combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, shutdownToken)) { CancellationToken combinedCancellationToken = combinedCancellationSource.Token; await WriteSiteExtensionManifestAsync(combinedCancellationToken); IStorageAccount dashboardAccount = await storageAccountProvider.GetDashboardAccountAsync(combinedCancellationToken); IHostInstanceLogger hostInstanceLogger = null; if (hostInstanceLogerProvider != null) { hostInstanceLogger = await hostInstanceLogerProvider.GetAsync(combinedCancellationToken); } else { hostInstanceLogger = await((IHostInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken); } IFunctionInstanceLogger functionInstanceLogger = null; if (functionInstanceLoggerProvider != null) { functionInstanceLogger = await functionInstanceLoggerProvider.GetAsync(combinedCancellationToken); } else { functionInstanceLogger = (IFunctionInstanceLogger)(await((IFunctionInstanceLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken)); } IFunctionOutputLogger functionOutputLogger = null; if (functionOutputLoggerProvider != null) { functionOutputLogger = await functionOutputLoggerProvider.GetAsync(combinedCancellationToken); } else { functionOutputLogger = (IFunctionOutputLogger)(await((IFunctionOutputLoggerProvider)loggerProvider).GetAsync(combinedCancellationToken)); } if (functionExecutor == null) { functionExecutor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher, trace); } if (functionIndexProvider == null) { functionIndexProvider = new FunctionIndexProvider(typeLocator, triggerBindingProvider, bindingProvider, activator, functionExecutor, extensions, singletonManager); } IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken); IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll(), singletonManager, activator, nameResolver, trace); IFunctionExecutor hostCallExecutor; IListener listener; HostOutputMessage hostOutputMessage; if (dashboardAccount != null) { string hostId = await hostIdProvider.GetHostIdAsync(cancellationToken); string sharedQueueName = HostQueueNames.GetHostQueueName(hostId); IStorageQueueClient dashboardQueueClient = dashboardAccount.CreateQueueClient(); IStorageQueue sharedQueue = dashboardQueueClient.GetQueueReference(sharedQueueName); IListenerFactory sharedQueueListenerFactory = new HostMessageListenerFactory(sharedQueue, queueConfiguration, backgroundExceptionDispatcher, trace, functions, functionInstanceLogger, functionExecutor); Guid hostInstanceId = Guid.NewGuid(); string instanceQueueName = HostQueueNames.GetHostQueueName(hostInstanceId.ToString("N")); IStorageQueue instanceQueue = dashboardQueueClient.GetQueueReference(instanceQueueName); IListenerFactory instanceQueueListenerFactory = new HostMessageListenerFactory(instanceQueue, queueConfiguration, backgroundExceptionDispatcher, trace, functions, functionInstanceLogger, functionExecutor); HeartbeatDescriptor heartbeatDescriptor = new HeartbeatDescriptor { SharedContainerName = HostContainerNames.Hosts, SharedDirectoryName = HostDirectoryNames.Heartbeats + "/" + hostId, InstanceBlobName = hostInstanceId.ToString("N"), ExpirationInSeconds = (int)HeartbeatIntervals.ExpirationInterval.TotalSeconds }; IStorageBlockBlob blob = dashboardAccount.CreateBlobClient() .GetContainerReference(heartbeatDescriptor.SharedContainerName) .GetBlockBlobReference(heartbeatDescriptor.SharedDirectoryName + "/" + heartbeatDescriptor.InstanceBlobName); IRecurrentCommand heartbeatCommand = new UpdateHostHeartbeatCommand(new HeartbeatCommand(blob)); IEnumerable<MethodInfo> indexedMethods = functions.ReadAllMethods(); Assembly hostAssembly = GetHostAssembly(indexedMethods); string displayName = hostAssembly != null ? hostAssembly.GetName().Name : "Unknown"; hostOutputMessage = new DataOnlyHostOutputMessage { HostInstanceId = hostInstanceId, HostDisplayName = displayName, SharedQueueName = sharedQueueName, InstanceQueueName = instanceQueueName, Heartbeat = heartbeatDescriptor, WebJobRunIdentifier = WebJobRunIdentifier.Current }; hostCallExecutor = CreateHostCallExecutor(instanceQueueListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken, functionExecutor); IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory, sharedQueueListenerFactory, instanceQueueListenerFactory); listener = CreateHostListener(hostListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken); // Publish this to Azure logging account so that a web dashboard can see it. await LogHostStartedAsync(functions, hostOutputMessage, hostInstanceLogger, combinedCancellationToken); } else { hostCallExecutor = new ShutdownFunctionExecutor(shutdownToken, functionExecutor); IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory); IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener); listener = shutdownListener; hostOutputMessage = new DataOnlyHostOutputMessage(); } functionExecutor.HostOutputMessage = hostOutputMessage; IEnumerable<FunctionDescriptor> descriptors = functions.ReadAllDescriptors(); int descriptorsCount = descriptors.Count(); if (descriptorsCount == 0) { trace.Warning("No functions found. Try making job classes and methods public.", TraceSource.Indexing); } else { StringBuilder functionsTrace = new StringBuilder(); functionsTrace.AppendLine("Found the following functions:"); foreach (FunctionDescriptor descriptor in descriptors) { functionsTrace.AppendLine(descriptor.FullName); } trace.Info(functionsTrace.ToString(), TraceSource.Indexing); } return new JobHostContext(functions, hostCallExecutor, listener, trace); } }
public FunctionIndexer(ITriggerBindingProvider triggerBindingProvider, IBindingProvider bindingProvider, IJobActivator activator, IFunctionExecutor executor, IExtensionRegistry extensions) { if (triggerBindingProvider == null) { throw new ArgumentNullException("triggerBindingProvider"); } if (bindingProvider == null) { throw new ArgumentNullException("bindingProvider"); } if (activator == null) { throw new ArgumentNullException("activator"); } if (executor == null) { throw new ArgumentNullException("executor"); } if (extensions == null) { throw new ArgumentNullException("extensions"); } _triggerBindingProvider = triggerBindingProvider; _bindingProvider = bindingProvider; _activator = activator; _executor = executor; _jobTypeAssemblies = new HashSet <Assembly>(GetJobTypeAssemblies(extensions, typeof(ITriggerBindingProvider), typeof(IBindingProvider))); }