Example #1
0
        private void FireSyncTriggers(ITracer tracer)
        {
            tracer.Trace("FunctionController.FireSyncTriggers");

            // create background tracer independent of request lifetime
            var bgTracer = new XmlTracer(_environment.TracePath, tracer.TraceLevel);

            // start new task to detach from request sync context
            Task.Run(async () =>
            {
                using (bgTracer.Step(XmlTracer.BackgroundTrace, new Dictionary<string, string>
                {
                    { "url", "/api/functions/synctriggers" },
                    { "method", "POST" }
                }))
                {
                    try
                    {
                        await _manager.SyncTriggersAsync(bgTracer);
                    }
                    catch (Exception ex)
                    {
                        bgTracer.TraceError(ex);
                    }
                }
            });
        }
Example #2
0
        private static ITracer GetTracer(IEnvironment env, TraceLevel level)
        {
            if (level > TraceLevel.Off)
            {
                var tracer = new XmlTracer(env.TracePath, level);
                string logFile = System.Environment.GetEnvironmentVariable(Constants.TraceFileEnvKey);
                if (!String.IsNullOrEmpty(logFile))
                {
                    // Kudu.exe is executed as part of git.exe (post-receive), giving its initial depth of 4 indentations
                    string logPath = Path.Combine(env.TracePath, logFile);
                    return new CascadeTracer(tracer, new TextTracer(logPath, level, 4));
                }

                return tracer;
            }

            return NullTracer.Instance;
        }
Example #3
0
        public async Task<HttpResponseMessage> InstallExtension(string id, SiteExtensionInfo requestInfo)
        {
            var startTime = DateTime.UtcNow;
            var tracer = _traceFactory.GetTracer();

            if (IsInstallationLockHeldSafeCheck(id))
            {
                tracer.Trace("{0} is installing with another request, reject current request with Conflict status.", id);
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Conflict, id));
            }

            if (requestInfo == null)
            {
                requestInfo = new SiteExtensionInfo();
            }

            tracer.Trace("Installing {0}, version: {1} from feed: {2}", id, requestInfo.Version, requestInfo.FeedUrl);
            SiteExtensionInfo result = await InitInstallSiteExtension(id, requestInfo.Type);

            if (ArmUtils.IsArmRequest(Request))
            {
                // create a context free tracer
                ITracer backgroundTracer = NullTracer.Instance;
                IDictionary<string, string> traceAttributes = new Dictionary<string, string>();

                if (tracer.TraceLevel == TraceLevel.Off)
                {
                    backgroundTracer = NullTracer.Instance;
                }

                if (tracer.TraceLevel > TraceLevel.Off)
                {
                    backgroundTracer = new XmlTracer(_environment.TracePath, tracer.TraceLevel);
                    traceAttributes = new Dictionary<string, string>()
                    {
                        {"url", Request.RequestUri.AbsolutePath},
                        {"method", Request.Method.Method}
                    };

                    foreach (var item in Request.Headers)
                    {
                        if (!traceAttributes.ContainsKey(item.Key))
                        {
                            traceAttributes.Add(item.Key, string.Join(",", item.Value));
                        }
                    }
                }

                AutoResetEvent installationSignal = new AutoResetEvent(false);

                // trigger installation, but do not wait. Expecting poll for status
                ThreadPool.QueueUserWorkItem((object stateInfo) =>
                {
                    using (backgroundTracer.Step(XmlTracer.BackgroundTrace, attributes: traceAttributes))
                    {
                        try
                        {
                            using (backgroundTracer.Step("Background thread started for {0} installation", id))
                            {
                                _manager.InstallExtension(id, requestInfo.Version, requestInfo.FeedUrl, requestInfo.Type, backgroundTracer).Wait();
                            }
                        }
                        finally
                        {
                            installationSignal.Set();

                            // will be a few millionseconds off if task finshed within 15 seconds.
                            LogEndEvent(id, (DateTime.UtcNow - startTime), backgroundTracer);
                        }
                    }
                });

                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                if (installationSignal.WaitOne(TimeSpan.FromSeconds(15)))
                {
                    if (!armSettings.IsRestartRequired(_siteExtensionRoot))
                    {
                        // only skip polling if current installation doesn`t require restart, to avoid making race condition common
                        // TODO: re-visit if we want to skip polling for case that need to restart
                        tracer.Trace("Installation finish quick and not require restart, skip async polling, invoking GET to return actual status to caller.");
                        return await GetLocalExtension(id);
                    }
                }

                // do not log end event here, since it is not done yet
                return Request.CreateResponse(HttpStatusCode.Created, ArmUtils.AddEnvelopeOnArmRequest<SiteExtensionInfo>(result, Request));
            }
            else
            {
                result = await _manager.InstallExtension(id, requestInfo.Version, requestInfo.FeedUrl, requestInfo.Type, tracer);

                if (string.Equals(Constants.SiteExtensionProvisioningStateFailed, result.ProvisioningState, StringComparison.OrdinalIgnoreCase))
                {
                    SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                    throw new HttpResponseException(Request.CreateErrorResponse(armSettings.Status, result.Comment));
                }

                var response = Request.CreateResponse(HttpStatusCode.OK, result);
                LogEndEvent(id, (DateTime.UtcNow - startTime), tracer);
                return response;
            }
        }