/// <summary> /// The asynchronous program entry-point. /// </summary> /// <returns> /// The process exit code. /// </returns> static async Task <int> AsyncMain() { using (ActivityCorrelationManager.BeginActivityScope()) using (Terminator terminator = new Terminator()) using (IContainer container = BuildContainer()) { // Force initialisation of logging. ILogger log = container.Resolve <ILogger>().ForContext(typeof(Program)); log.Debug("Creating language server..."); var server = container.Resolve <LSP.Server.LanguageServer>(); log.Debug("Waiting for client to initialise language server..."); Task initializeTask = server.Initialize(); // Special case for probing whether language server is startable given current runtime environment. string[] commandLineArguments = Environment.GetCommandLineArgs(); if (commandLineArguments.Length == 2 && commandLineArguments[1] == "--probe") { // Give the language server a chance to start. await Task.Yield(); // Show any exception encountered while starting the language server. if (initializeTask.IsFaulted || initializeTask.IsCanceled) { await initializeTask; } Console.Error.WriteLine("PROBE: Yes, the language server can start."); return(0); } await initializeTask; log.Debug("Language server initialised by client."); if (server.Client.ProcessId != null) { terminator.Initialize( (int)server.Client.ProcessId.Value ); } await server.WasShutDown; log.Debug("Language server is shutting down..."); await server.WaitForExit; log.Debug("Server has shut down. Preparing to terminate server process..."); log.Debug("Server process is ready to terminate."); return(0); } }
/// <summary> /// The asynchronous program entry-point. /// </summary> /// <returns> /// The process exit code. /// </returns> static async Task <int> AsyncMain() { using (ActivityCorrelationManager.BeginActivityScope()) using (Terminator terminator = new Terminator()) using (IContainer container = BuildContainer()) { // Force initialisation of logging. ILogger log = container.Resolve <ILogger>().ForContext(typeof(Program)); log.Debug("Creating language server..."); var server = container.Resolve <LSP.Server.LanguageServer>(); log.Debug("Waiting for client to initialise language server..."); Task initializeTask = server.Initialize(); // Special case for probing whether language server is startable given current runtime environment. string[] commandLineArguments = Environment.GetCommandLineArgs(); if (commandLineArguments.Length == 2 && commandLineArguments[1] == "--probe") { // Give the language server a chance to start. await Task.Yield(); // Show any exception encountered while starting the language server. if (initializeTask.IsFaulted || initializeTask.IsCanceled) { await initializeTask; } Console.Error.WriteLine("PROBE: Yes, the language server can start."); return(0); } await initializeTask; log.Debug("Language server initialised by client."); await server.WasShutDown; log.Debug("Language server is shutting down..."); await server.WaitForExit; log.Debug("Server has shut down. Preparing to terminate server process..."); // AF: Temporary fix for tintoy/msbuild-project-tools-vscode#36 // // The server hangs while waiting for LSP's ProcessScheduler thread to terminate so, after a timeout has elapsed, we forcibly terminate this process. terminator.TerminateAfter( TimeSpan.FromSeconds(3) ); log.Debug("Server process is ready to terminate."); return(0); } }
/// <summary> /// The asynchronous program entry-point. /// </summary> /// <returns> /// A <see cref="Task"/> representing program execution. /// </returns> static async Task AsyncMain() { using (ActivityCorrelationManager.BeginActivityScope()) using (IContainer container = BuildContainer()) { var server = container.Resolve <LSP.Server.LanguageServer>(); await server.Initialize(); await server.WasShutDown; } }
/// <summary> /// Add an activity / log-context scope for an operation. /// </summary> /// <param name="operationName"> /// The operation name. /// </param> /// <returns> /// An <see cref="IDisposable"/> representing the log-context scope. /// </returns> protected IDisposable BeginOperation(string operationName) { if (String.IsNullOrWhiteSpace(operationName)) { throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'operationName'.", nameof(operationName)); } return(new CompositeDisposable( ActivityCorrelationManager.BeginActivityScope(), Serilog.Context.LogContext.PushProperty("Operation", operationName) )); }
/// <summary> /// Asynchronously process an HTTP request message and its response. /// </summary> /// <param name="request"> /// The outgoing <see cref="HttpRequestMessage"/>. /// </param> /// <param name="cancellationToken"> /// A <see cref="CancellationToken"/> that can be used to cancel the asynchronous operation. /// </param> /// <returns> /// The incoming HTTP response message. /// </returns> protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } Guid?activityId = ActivityCorrelationManager.GetCurrentActivityId(); if (activityId.HasValue) { request.Headers.Remove("X-ActivityId"); request.Headers.Add("X-ActivityId", activityId.Value.ToString() ); } return(base.SendAsync(request, cancellationToken)); }
/// <summary> /// Asynchronously invoke the middleware to process the specified request. /// </summary> /// <param name="context"> /// The <see cref="HttpContext"/> representing the request. /// </param> /// <returns> /// A <see cref="Task"/> representing the asynchronous operation. /// </returns> public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // Set up the correlation manager for the current request. ActivityCorrelationManager requestCorrelationManager = context.RequestServices.GetService <ActivityCorrelationManager>(); ActivityCorrelationManager previousCorrelationManager = ActivityCorrelationManager.Current; if (_setCurrentCorrelationManager) { ActivityCorrelationManager.Current = requestCorrelationManager; } // Get or create the request activity Id. Guid requestActivityId = GetActivityIdFromHeader(context) // First try for activity Id from header. ?? GetActivityIdFromTraceIdentifier(context) // Fall back to ASP.NET's activity Id. ?? Guid.NewGuid(); // Otherwise, create a new activity. requestCorrelationManager.ActivityId = requestActivityId; context.TraceIdentifier = requestActivityId.ToString(); try { await _nextMiddleware(context); } finally { if (_setCurrentCorrelationManager) { ActivityCorrelationManager.Current = previousCorrelationManager; } context.Response.Headers[_headerName] = requestActivityId.ToString(); } }
/// <summary> /// Asynchronously invoke the middleware to process the specified request. /// </summary> /// <param name="context"> /// The <see cref="HttpContext"/> representing the request. /// </param> /// <returns> /// A <see cref="Task"/> representing the asynchronous operation. /// </returns> public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Guid requestActivityId = GetOrCreateActivityId(context); using (CreateActivityLogScope(context, requestActivityId)) { // Override current activity Id. context.TraceIdentifier = requestActivityId.ToString(); // Set up the correlation manager for the current request. ActivityCorrelationManager previousCorrelationManager = ActivityCorrelationManager.Current; ActivityCorrelationManager requestCorrelationManager = context.RequestServices.GetRequiredService <ActivityCorrelationManager>(); if (_setCurrentCorrelationManager) { ActivityCorrelationManager.Current = requestCorrelationManager; } try { using (requestCorrelationManager.BeginActivity(requestActivityId)) { await _nextMiddleware(context); } } finally { if (_setCurrentCorrelationManager) { ActivityCorrelationManager.Current = previousCorrelationManager; } context.Response.Headers[_headerName] = requestActivityId.ToString(); } } }
/// <summary> /// The asynchronous program entry-point. /// </summary> /// <returns> /// A <see cref="Task"/> representing program execution. /// </returns> static async Task AsyncMain() { using (ActivityCorrelationManager.BeginActivityScope()) using (Terminator terminator = new Terminator()) using (IContainer container = BuildContainer()) { // Force initialisation of logging. ILogger log = container.Resolve <ILogger>().ForContext(typeof(Program)); log.Debug("Creating language server..."); var server = container.Resolve <LSP.Server.LanguageServer>(); log.Debug("Waiting for client to initialise language server..."); await server.Initialize(); log.Debug("Language server initialised by client."); await server.WasShutDown; log.Debug("Language server is shutting down..."); await server.WaitForExit; log.Debug("Server has shut down. Preparing to terminate server process..."); // AF: Temporary fix for tintoy/msbuild-project-tools-vscode#36 // // The server hangs while waiting for LSP's ProcessScheduler thread to terminate so, after a timeout has elapsed, we forcibly terminate this process. terminator.TerminateAfter( TimeSpan.FromSeconds(3) ); log.Debug("Server process is ready to terminate."); } }