Beispiel #1
0
        public IActionResult DrainStatus([FromServices] IScriptHostManager scriptHostManager)
        {
            if (Utility.TryGetHostService(scriptHostManager, out IFunctionActivityStatusProvider functionActivityStatusProvider) &&
                Utility.TryGetHostService(scriptHostManager, out IDrainModeManager drainModeManager))
            {
                var            functionActivityStatus = functionActivityStatusProvider.GetStatus();
                DrainModeState state = DrainModeState.Disabled;
                if (drainModeManager.IsDrainModeEnabled)
                {
                    state = (functionActivityStatus.OutstandingInvocations == 0 && functionActivityStatus.OutstandingRetries == 0)
                            ? DrainModeState.Completed : DrainModeState.InProgress;
                }

                DrainModeStatus status = new DrainModeStatus()
                {
                    State = state
                };

                string message = $"Drain Status: {JsonConvert.SerializeObject(state, Formatting.Indented)}, Activity Status: {JsonConvert.SerializeObject(functionActivityStatus, Formatting.Indented)}";
                _logger.LogDebug(message);

                return(Ok(status));
            }
            else
            {
                return(StatusCode(StatusCodes.Status503ServiceUnavailable));
            }
        }
Beispiel #2
0
        public async Task <IActionResult> Drain([FromServices] IScriptHostManager scriptHostManager)
        {
            _logger.LogDebug("Received request to drain the host");

            if (!Utility.TryGetHostService(scriptHostManager, out IDrainModeManager drainModeManager))
            {
                return(StatusCode(StatusCodes.Status503ServiceUnavailable));
            }

            await _drainSemaphore.WaitAsync();

            // Stop call to some listeners gets stuck, not waiting for the stop call to complete
            _ = drainModeManager.EnableDrainModeAsync(CancellationToken.None)
                .ContinueWith(
                antecedent =>
            {
                if (antecedent.Status == TaskStatus.Faulted)
                {
                    _logger.LogError(antecedent.Exception, "Something went wrong invoking drain mode");
                }

                _drainSemaphore.Release();
            });
            return(Accepted());
        }
Beispiel #3
0
        public async Task <IActionResult> Resume([FromServices] IScriptHostManager scriptHostManager)
        {
            try
            {
                await _resumeSemaphore.WaitAsync();

                ScriptHostState currentState = scriptHostManager.State;

                _logger.LogDebug($"Received request to resume a draining host - host status: {currentState.ToString()}");

                if (currentState != ScriptHostState.Running ||
                    !Utility.TryGetHostService(scriptHostManager, out IDrainModeManager drainModeManager))
                {
                    _logger.LogDebug("The host is not in a state where we can resume.");
                    return(StatusCode(StatusCodes.Status409Conflict));
                }

                _logger.LogDebug($"Drain mode enabled: {drainModeManager.IsDrainModeEnabled}");

                if (drainModeManager.IsDrainModeEnabled)
                {
                    _logger.LogDebug("Starting a new host");
                    await scriptHostManager.RestartHostAsync();
                }

                var status = new ResumeStatus {
                    State = scriptHostManager.State
                };
                return(Ok(status));
            }
            finally
            {
                _resumeSemaphore.Release();
            }
        }
Beispiel #4
0
        public async Task Invoke(HttpContext httpContext, IScriptHostManager scriptHostManager)
        {
            if (scriptHostManager.State != ScriptHostState.Offline)
            {
                using (Logger.VerifyingHostAvailabilityScope(_logger, httpContext.TraceIdentifier))
                {
                    Logger.InitiatingHostAvailabilityCheck(_logger);

                    bool hostReady = await scriptHostManager.DelayUntilHostReady();

                    if (!hostReady)
                    {
                        Logger.HostUnavailableAfterCheck(_logger);

                        httpContext.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                        await httpContext.Response.WriteAsync("Function host is not running.");

                        return;
                    }

                    Logger.HostAvailabilityCheckSucceeded(_logger);

                    await _next.Invoke(httpContext);
                }
            }
            else
            {
                // host is offline so return the app_offline.htm file content
                var offlineFilePath = Path.Combine(_applicationHostOptions.CurrentValue.ScriptPath, ScriptConstants.AppOfflineFileName);
                httpContext.Response.ContentType = "text/html";
                httpContext.Response.StatusCode  = StatusCodes.Status503ServiceUnavailable;
                await httpContext.Response.SendFileAsync(offlineFilePath);
            }
        }
Beispiel #5
0
        public FileMonitoringService(IOptions <ScriptJobHostOptions> scriptOptions, ILoggerFactory loggerFactory, IScriptEventManager eventManager, IApplicationLifetime applicationLifetime, IScriptHostManager scriptHostManager, IEnvironment environment)
        {
            _scriptOptions       = scriptOptions.Value;
            _eventManager        = eventManager;
            _applicationLifetime = applicationLifetime;
            _scriptHostManager   = scriptHostManager;
            _hostLogPath         = Path.Combine(_scriptOptions.RootLogPath, "Host");
            _logger      = loggerFactory.CreateLogger(LogCategories.Startup);
            _environment = environment;

            // Use this for newer logs as we can't change existing categories of log messages
            _typedLogger = loggerFactory.CreateLogger <FileMonitoringService>();

            // If a file change should result in a restart, we debounce the event to
            // ensure that only a single restart is triggered within a specific time window.
            // This allows us to deal with a large set of file change events that might
            // result from a bulk copy/unzip operation. In such cases, we only want to
            // restart after ALL the operations are complete and there is a quiet period.
            _restart = RestartAsync;
            _restart = _restart.Debounce(500);

            _shutdown = Shutdown;
            _shutdown = _shutdown.Debounce(milliseconds: 500);
            _rootDirectorySnapshot = GetDirectorySnapshot();
        }
 public StandbyManager(IScriptHostManager scriptHostManager, IOptionsMonitor <ScriptApplicationHostOptions> options, ILoggerFactory loggerFactory)
 {
     _scriptHostManager  = scriptHostManager ?? throw new ArgumentNullException(nameof(scriptHostManager));
     _options            = options ?? throw new ArgumentNullException(nameof(options));
     _logger             = loggerFactory.CreateLogger(LogCategories.Startup);
     _specializationTask = new Lazy <Task>(SpecializeHostCoreAsync, LazyThreadSafetyMode.ExecutionAndPublication);
 }
        public async Task <IActionResult> Warmup([FromServices] IScriptHostManager scriptHostManager)
        {
            // Endpoint only for Windows Elastic Premium or Linux App Service plans
            if (!(_environment.IsLinuxAppService() || _environment.IsWindowsElasticPremium()))
            {
                return(BadRequest("This API is not available for the current hosting plan"));
            }

            if (Interlocked.CompareExchange(ref _warmupExecuted, 1, 0) != 0)
            {
                return(Ok());
            }

            if (scriptHostManager is IServiceProvider serviceProvider)
            {
                IScriptJobHost jobHost = serviceProvider.GetService <IScriptJobHost>();

                if (jobHost == null)
                {
                    _logger.LogError($"No active host available.");
                    return(StatusCode(503));
                }

                await jobHost.TryInvokeWarmupAsync();

                return(Ok());
            }

            return(BadRequest("This API is not supported by the current hosting environment."));
        }
 public HostWarmupMiddleware(RequestDelegate next, IScriptWebHostEnvironment webHostEnvironment, IEnvironment environment, IScriptHostManager hostManager)
 {
     _next = next;
     _webHostEnvironment = webHostEnvironment;
     _environment        = environment;
     _hostManager        = hostManager;
 }
        public async Task Invoke(HttpContext httpContext, IScriptHostManager scriptHostManager)
        {
            if (scriptHostManager.State != ScriptHostState.Offline)
            {
                using (Logger.VerifyingHostAvailabilityScope(_logger, httpContext.TraceIdentifier))
                {
                    Logger.InitiatingHostAvailabilityCheck(_logger);

                    bool hostReady = await scriptHostManager.DelayUntilHostReady();

                    if (!hostReady)
                    {
                        Logger.HostUnavailableAfterCheck(_logger);

                        httpContext.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                        await httpContext.Response.WriteAsync("Function host is not running.");

                        return;
                    }

                    Logger.HostAvailabilityCheckSucceeded(_logger);

                    await _next.Invoke(httpContext);
                }
            }
            else
            {
                await httpContext.SetOfflineResponseAsync(_applicationHostOptions.CurrentValue.ScriptPath);
            }
        }
 public InfiniteTimerStandbyManager(IScriptHostManager scriptHostManager, IWebHostRpcWorkerChannelManager rpcWorkerChannelManager,
                                    IConfiguration configuration, IScriptWebHostEnvironment webHostEnvironment, IEnvironment environment,
                                    IOptionsMonitor <ScriptApplicationHostOptions> options, ILogger <StandbyManager> logger, HostNameProvider hostNameProvider, IApplicationLifetime applicationLifetime)
     : base(scriptHostManager, rpcWorkerChannelManager, configuration, webHostEnvironment, environment, options,
            logger, hostNameProvider, applicationLifetime, TimeSpan.FromMilliseconds(-1), new TestMetricsLogger())
 {
 }
 public HostAvailabilityCheckMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptionsMonitor <ScriptApplicationHostOptions> applicationHostOptions, IScriptHostManager scriptHostManager)
 {
     _next   = next;
     _logger = loggerFactory.CreateLogger <HostAvailabilityCheckMiddleware>();
     _applicationHostOptions = applicationHostOptions;
     _scriptHostManager      = scriptHostManager;
 }
        public HostAzureBlobStorageProvider(IScriptHostManager scriptHostManager, IConfiguration configuration, IOptionsMonitor <JobHostInternalStorageOptions> options, ILogger <HostAzureBlobStorageProvider> logger, AzureComponentFactory componentFactory, AzureEventSourceLogForwarder logForwarder)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            _storageOptions = options ?? throw new ArgumentNullException(nameof(options));
            _logger         = logger ?? throw new ArgumentNullException(nameof(logger));

            _blobServiceClientProvider = new BlobServiceClientProvider(componentFactory, logForwarder);

            if (FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableMergedWebHostScriptHostConfiguration))
            {
                Configuration = configuration;
            }
            else
            {
                if (scriptHostManager == null)
                {
                    throw new ArgumentNullException(nameof(scriptHostManager));
                }

                Configuration = new ConfigurationBuilder()
                                .Add(new ActiveHostConfigurationSource(scriptHostManager))
                                .AddConfiguration(configuration)
                                .Build();
            }
        }
Beispiel #13
0
        public async Task <IActionResult> GetHostStatus([FromServices] IScriptHostManager scriptHostManager, [FromServices] IHostIdProvider hostIdProvider)
        {
            var status = new HostStatus
            {
                State          = scriptHostManager.State.ToString(),
                Version        = ScriptHost.Version,
                VersionDetails = Utility.GetInformationalVersion(typeof(ScriptHost)),
                Id             = await hostIdProvider.GetHostIdAsync(CancellationToken.None),
                ProcessUptime  = (long)(DateTime.UtcNow - Process.GetCurrentProcess().StartTime).TotalMilliseconds
            };

            var lastError = scriptHostManager.LastError;

            if (lastError != null)
            {
                status.Errors = new Collection <string>();
                status.Errors.Add(Utility.FlattenException(lastError));
            }

            string message = $"Host Status: {JsonConvert.SerializeObject(status, Formatting.Indented)}";

            _logger.LogInformation(message);

            return(Ok(status));
        }
 public InfiniteTimerStandbyManager(IScriptHostManager scriptHostManager, IWebHostLanguageWorkerChannelManager languageWorkerChannelManager,
                                    IConfiguration configuration, IScriptWebHostEnvironment webHostEnvironment, IEnvironment environment,
                                    IOptionsMonitor <ScriptApplicationHostOptions> options, ILogger <StandbyManager> logger, HostNameProvider hostNameProvider)
     : base(scriptHostManager, languageWorkerChannelManager, configuration, webHostEnvironment, environment, options,
            logger, hostNameProvider, TimeSpan.FromMilliseconds(-1))
 {
 }
 public HostWarmupMiddleware(RequestDelegate next, IScriptWebHostEnvironment webHostEnvironment, IEnvironment environment, IScriptHostManager hostManager, ILogger <HostWarmupMiddleware> logger)
 {
     _next = next;
     _webHostEnvironment = webHostEnvironment;
     _environment        = environment;
     _hostManager        = hostManager;
     _logger             = logger;
     _assemblyLocalPath  = Path.GetDirectoryName(new Uri(typeof(HostWarmupMiddleware).Assembly.Location).LocalPath);
 }
Beispiel #16
0
 public KeysController(IOptions <ScriptApplicationHostOptions> applicationOptions, ISecretManagerProvider secretManagerProvider, ILoggerFactory loggerFactory, IFileSystem fileSystem, IFunctionsSyncManager functionsSyncManager, IScriptHostManager hostManager)
 {
     _applicationOptions    = applicationOptions;
     _secretManagerProvider = secretManagerProvider;
     _logger               = loggerFactory.CreateLogger(ScriptConstants.LogCategoryKeysController);
     _fileSystem           = fileSystem;
     _functionsSyncManager = functionsSyncManager;
     _hostManager          = hostManager;
 }
Beispiel #17
0
        public async Task <IActionResult> Disable([FromServices] IScriptHostManager hostManager)
        {
            _logger.LogDebug("Disabling container");
            // Mark the container disabled. We check for this on host restart
            await Utility.MarkContainerDisabled(_logger);

            var tIgnore = Task.Run(() => hostManager.RestartHostAsync());

            return(Ok());
        }
Beispiel #18
0
        public FunctionsSyncService(ILoggerFactory loggerFactory, IScriptHostManager scriptHostManager, IPrimaryHostStateProvider primaryHostStateProvider, IFunctionsSyncManager functionsSyncManager)
        {
            ArgumentNullException.ThrowIfNull(loggerFactory);

            DueTime                   = 30 * 1000;
            _scriptHostManager        = scriptHostManager;
            _primaryHostStateProvider = primaryHostStateProvider;
            _functionsSyncManager     = functionsSyncManager;
            _logger                   = loggerFactory.CreateLogger(ScriptConstants.LogCategoryHostGeneral);
        }
Beispiel #19
0
 public IActionResult GetConfig([FromServices] IScriptHostManager scriptHostManager)
 {
     if (Utility.TryGetHostService(scriptHostManager, out IHostOptionsProvider provider))
     {
         return(Ok(provider.GetOptions().ToString()));
     }
     else
     {
         return(StatusCode(StatusCodes.Status503ServiceUnavailable));
     }
 }
 public StandbyManager(IScriptHostManager scriptHostManager, ILanguageWorkerChannelManager languageWorkerChannelManager, IConfiguration configuration, IScriptWebHostEnvironment webHostEnvironment,
                       IEnvironment environment, IOptionsMonitor <ScriptApplicationHostOptions> options, ILogger <StandbyManager> logger)
 {
     _scriptHostManager            = scriptHostManager ?? throw new ArgumentNullException(nameof(scriptHostManager));
     _options                      = options ?? throw new ArgumentNullException(nameof(options));
     _logger                       = logger ?? throw new ArgumentNullException(nameof(logger));
     _specializationTask           = new Lazy <Task>(SpecializeHostCoreAsync, LazyThreadSafetyMode.ExecutionAndPublication);
     _webHostEnvironment           = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
     _environment                  = environment ?? throw new ArgumentNullException(nameof(environment));
     _configuration                = configuration as IConfigurationRoot ?? throw new ArgumentNullException(nameof(configuration));
     _languageWorkerChannelManager = languageWorkerChannelManager ?? throw new ArgumentNullException(nameof(languageWorkerChannelManager));
 }
Beispiel #21
0
        public ActiveHostWebJobsOptionsSetup(IScriptHostManager scriptHostManager, IConfiguration configuration)
        {
            if (scriptHostManager == null)
            {
                throw new ArgumentNullException(nameof(scriptHostManager));
            }

            _configuration = new ConfigurationBuilder()
                             .Add(new ActiveHostConfigurationSource(scriptHostManager))
                             .AddConfiguration(configuration)
                             .Build();
        }
Beispiel #22
0
        public IActionResult Ping([FromServices] IScriptHostManager scriptHostManager)
        {
            var pingStatus = new JObject
            {
                { "hostState", scriptHostManager.State.ToString() }
            };

            string message = $"Ping Status: {pingStatus.ToString()}";

            _logger.Log(LogLevel.Debug, new EventId(0, "PingStatus"), message);

            return(Ok());
        }
 public HostController(IOptions <ScriptApplicationHostOptions> applicationHostOptions,
                       ILoggerFactory loggerFactory,
                       IEnvironment environment,
                       IScriptHostManager scriptHostManager,
                       IFunctionsSyncManager functionsSyncManager,
                       HostPerformanceManager performanceManager)
 {
     _applicationHostOptions = applicationHostOptions;
     _logger               = loggerFactory.CreateLogger(ScriptConstants.LogCategoryHostController);
     _environment          = environment;
     _scriptHostManager    = scriptHostManager;
     _functionsSyncManager = functionsSyncManager;
     _performanceManager   = performanceManager;
 }
 public StandbyManager(IScriptHostManager scriptHostManager, ILanguageWorkerChannelManager languageWorkerChannelManager, IConfiguration configuration, IScriptWebHostEnvironment webHostEnvironment,
                       IEnvironment environment, IOptionsMonitor <ScriptApplicationHostOptions> options, ILogger <StandbyManager> logger, HostNameProvider hostNameProvider)
 {
     _scriptHostManager               = scriptHostManager ?? throw new ArgumentNullException(nameof(scriptHostManager));
     _options                         = options ?? throw new ArgumentNullException(nameof(options));
     _logger                          = logger ?? throw new ArgumentNullException(nameof(logger));
     _specializationTask              = new Lazy <Task>(SpecializeHostCoreAsync, LazyThreadSafetyMode.ExecutionAndPublication);
     _webHostEnvironment              = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
     _environment                     = environment ?? throw new ArgumentNullException(nameof(environment));
     _configuration                   = configuration as IConfigurationRoot ?? throw new ArgumentNullException(nameof(configuration));
     _languageWorkerChannelManager    = languageWorkerChannelManager ?? throw new ArgumentNullException(nameof(languageWorkerChannelManager));
     _hostNameProvider                = hostNameProvider ?? throw new ArgumentNullException(nameof(hostNameProvider));
     _changeTokenCallbackSubscription = ChangeToken.RegisterChangeCallback(_ => _logger.LogDebug($"{nameof(StandbyManager)}.{nameof(ChangeToken)} callback has fired."), null);
 }
        internal static bool TryGetHostService <TService>(IScriptHostManager scriptHostManager, out TService service) where TService : class
        {
            service = null;

            try
            {
                service = (scriptHostManager as IServiceProvider)?.GetService <TService>();
            }
            catch
            {
                // can get exceptions if the host is being disposed
            }

            return(service != null);
        }
        public async Task Invoke(HttpContext httpContext, IScriptHostManager manager, ILogger <TestMiddleware> logger)
        {
            if (httpContext.Request.Query.ContainsKey("reset"))
            {
                await manager.RestartHostAsync(CancellationToken.None);

                logger.LogWarning("Environment reset");
                var features        = httpContext.Features;
                var servicesFeature = features.Get <IServiceProvidersFeature>();

                features.Set <IServiceProvidersFeature>(new RequestServicesFeature(httpContext, _scopeFactory));
            }

            await _next(httpContext);
        }
 public HostController(IOptions <ScriptApplicationHostOptions> applicationHostOptions,
                       IOptions <JobHostOptions> hostOptions,
                       ILoggerFactory loggerFactory,
                       IAuthorizationService authorizationService,
                       IWebFunctionsManager functionsManager,
                       IEnvironment environment,
                       IScriptHostManager scriptHostManager)
 {
     _applicationHostOptions = applicationHostOptions;
     _hostOptions            = hostOptions;
     _logger = loggerFactory.CreateLogger(ScriptConstants.LogCategoryHostController);
     _authorizationService = authorizationService;
     _functionsManager     = functionsManager;
     _environment          = environment;
     _scriptHostManager    = scriptHostManager;
 }
        public static async Task <bool> DelayUntilHostReady(this IScriptHostManager hostManager, int timeoutSeconds = ScriptConstants.HostTimeoutSeconds, int pollingIntervalMilliseconds = ScriptConstants.HostPollingIntervalMilliseconds)
        {
            if (CanInvoke(hostManager))
            {
                return(true);
            }
            else
            {
                await Utility.DelayAsync(timeoutSeconds, pollingIntervalMilliseconds, () =>
                {
                    return(!CanInvoke(hostManager) && hostManager.State != ScriptHostState.Error);
                });

                return(CanInvoke(hostManager));
            }
        }
        public static async Task <bool> DelayUntilHostReady(this IScriptHostManager hostManager, int timeoutSeconds = ScriptConstants.HostTimeoutSeconds, int pollingIntervalMilliseconds = ScriptConstants.HostPollingIntervalMilliseconds)
        {
            bool CanInvoke()
            {
                return(hostManager.State == ScriptHostState.Running || hostManager.State == ScriptHostState.Initialized);
            }

            await Utility.DelayAsync(timeoutSeconds, pollingIntervalMilliseconds, () =>
            {
                return(!CanInvoke() &&
                       hostManager.State != ScriptHostState.Error);
            });

            bool hostReady = CanInvoke();

            return(hostReady);
        }
Beispiel #30
0
        public async Task <IActionResult> GetHostStatus([FromServices] IScriptHostManager scriptHostManager, [FromServices] IHostIdProvider hostIdProvider, [FromServices] IServiceProvider serviceProvider = null)
        {
            // When making changes to HostStatus, ensure that you update the HostStatus class in AAPT-Antares-Websites repo as well.
            var status = new HostStatus
            {
                State           = scriptHostManager.State.ToString(),
                Version         = ScriptHost.Version,
                VersionDetails  = Utility.GetInformationalVersion(typeof(ScriptHost)),
                PlatformVersion = _environment.GetAntaresVersion(),
                InstanceId      = _environment.GetInstanceId(),
                ComputerName    = _environment.GetAntaresComputerName(),
                Id            = await hostIdProvider.GetHostIdAsync(CancellationToken.None),
                ProcessUptime = (long)(DateTime.UtcNow - Process.GetCurrentProcess().StartTime).TotalMilliseconds,
                FunctionAppContentEditingState = Utility.GetFunctionAppContentEditingState(_environment, _applicationHostOptions)
            };

            var bundleManager = serviceProvider.GetService <IExtensionBundleManager>();

            if (bundleManager != null)
            {
                var bundleInfo = await bundleManager.GetExtensionBundleDetails();

                if (bundleInfo != null)
                {
                    status.ExtensionBundle = new Models.ExtensionBundle()
                    {
                        Id      = bundleInfo.Id,
                        Version = bundleInfo.Version
                    };
                }
            }

            var lastError = scriptHostManager.LastError;

            if (lastError != null)
            {
                status.Errors = new Collection <string>();
                status.Errors.Add(Utility.FlattenException(lastError));
            }

            string message = $"Host Status: {JsonConvert.SerializeObject(status, Formatting.Indented)}";

            _logger.LogInformation(message);

            return(Ok(status));
        }