public async Task <string> GetHostIdAsync(CancellationToken cancellationToken) { CloudStorageAccount account; try { account = _storageAccountProvider.GetStorageAccount(); } catch (InvalidOperationException exception) { throw new InvalidOperationException( "A host ID is required. Either set JobHostConfiguration.HostId or provide a valid storage " + "connection string.", exception); } IFunctionIndex index = await _getFunctionIndexProvider.GetAsync(cancellationToken); IEnumerable <MethodInfo> indexedMethods = index.ReadAllMethods(); string sharedHostName = GetSharedHostName(indexedMethods, account); var directory = account.CreateCloudBlobClient().GetContainerReference( HostContainerNames.Hosts).GetDirectoryReference(HostDirectoryNames.Ids); return(await GetOrCreateHostIdAsync(sharedHostName, directory, cancellationToken)); }
public FunctionMetadata GetFunctionMetadata(string functionName) { FunctionMetadata result = null; var index = _functionIndexProvider.GetAsync(CancellationToken.None).GetAwaiter().GetResult(); var functionDefinition = index.LookupByName(functionName); if (functionDefinition != null) { result = new FunctionMetadata() { IsDisabled = functionDefinition.Descriptor.IsDisabled }; } return result; }
internal static async Task <JobHostContext> CreateAndLogHostStartedAsync( IStorageAccountProvider storageAccountProvider, IFunctionIndexProvider functionIndexProvider, IBindingProvider bindingProvider, IHostIdProvider hostIdProvider, IHostInstanceLoggerProvider hostInstanceLoggerProvider, IFunctionInstanceLoggerProvider functionInstanceLoggerProvider, IFunctionOutputLoggerProvider functionOutputLoggerProvider, IQueueConfiguration queueConfiguration, IBackgroundExceptionDispatcher backgroundExceptionDispatcher, IConsoleProvider consoleProvider, CancellationToken shutdownToken, CancellationToken cancellationToken) { 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); IFunctionIndex functions = await functionIndexProvider.GetAsync(combinedCancellationToken); IListenerFactory functionsListenerFactory = new HostListenerFactory(functions.ReadAll()); FunctionExecutor executor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher); TextWriter consoleOut = consoleProvider.Out; 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, consoleOut, functions, functionInstanceLogger); Guid hostInstanceId = Guid.NewGuid(); string instanceQueueName = HostQueueNames.GetHostQueueName(hostInstanceId.ToString("N")); IStorageQueue instanceQueue = dashboardQueueClient.GetQueueReference(instanceQueueName); IListenerFactory instanceQueueListenerFactory = new HostMessageListenerFactory(instanceQueue, queueConfiguration, backgroundExceptionDispatcher, consoleOut, functions, functionInstanceLogger); HeartbeatDescriptor heartbeatDescriptor = new HeartbeatDescriptor { SharedContainerName = HostContainerNames.Hosts, SharedDirectoryName = HostDirectoryNames.Heartbeats + "/" + hostId, InstanceBlobName = hostInstanceId.ToString("N"), ExpirationInSeconds = (int)HeartbeatIntervals.ExpirationInterval.TotalSeconds }; IRecurrentCommand heartbeatCommand = new UpdateHostHeartbeatCommand(new HeartbeatCommand( dashboardAccount, heartbeatDescriptor.SharedContainerName, heartbeatDescriptor.SharedDirectoryName + "/" + heartbeatDescriptor.InstanceBlobName)); 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, executor); IListenerFactory hostListenerFactory = new CompositeListenerFactory(functionsListenerFactory, sharedQueueListenerFactory, instanceQueueListenerFactory); listener = CreateHostListener(hostListenerFactory, heartbeatCommand, backgroundExceptionDispatcher, shutdownToken, executor); // 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, executor); IListener factoryListener = new ListenerFactoryListener(functionsListenerFactory, executor); IListener shutdownListener = new ShutdownListener(shutdownToken, factoryListener); listener = shutdownListener; hostOutputMessage = new DataOnlyHostOutputMessage(); } executor.HostOutputMessage = hostOutputMessage; IEnumerable <FunctionDescriptor> descriptors = functions.ReadAllDescriptors(); int descriptorsCount = descriptors.Count(); if (descriptorsCount == 0) { consoleOut.WriteLine( "No functions found. Try making job classes and methods public."); } else { consoleOut.WriteLine("Found the following functions:"); foreach (FunctionDescriptor descriptor in descriptors) { consoleOut.WriteLine(descriptor.FullName); } } return(new JobHostContext(functions, hostCallExecutor, listener, consoleOut)); } }