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;
        }
示例#5
0
 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);
        }
示例#8
0
        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));
        }
示例#9
0
        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;
            }
        }
示例#11
0
        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.");
 }
示例#13
0
        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);
            }
        }
示例#14
0
        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));
        }
示例#15
0
 public HostListenerFactory(IEnumerable <IFunctionDefinition> functionDefinitions, SingletonManager singletonManager, IJobActivator activator, INameResolver nameResolver, TraceWriter trace)
 {
     _functionDefinitions = functionDefinitions;
     _singletonManager    = singletonManager;
     _activator           = activator;
     _nameResolver        = nameResolver;
     _trace = trace;
 }
示例#16
0
 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 });
            }
        }
示例#18
0
        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
            });
        }
示例#22
0
        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);
 }
示例#24
0
 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;
 }
示例#25
0
        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;
                }
            }
        }
示例#26
0
        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));
            }
        }
示例#27
0
 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));
            }
        }
示例#29
0
        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));
            }
        }
示例#33
0
        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);
        }
示例#34
0
        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 }));
            }
        }
示例#37
0
        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);
            }
        }
示例#41
0
        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)));
        }