private async Task StartAsync() { base.Start(); var eventService = services.GetRequiredService <IEventService>(); eventService.Events <WorkspaceReadyEvent, IWorkspace>().On += (workspace) => { logger?.LogInformation( "Workspace ready {Time} after startup.", DateTime.UtcNow - System.Diagnostics.Process.GetCurrentProcess().StartTime.ToUniversalTime() ); }; // Before anything else, make sure to start the right background // thread on the Q# compilation loader to initialize serializers // and deserializers. Since that runs in the background, starting // the engine should not be blocked, and other services can // continue to initialize while the Q# compilation loader works. // // For more details, see: // https://github.com/microsoft/qsharp-compiler/pull/727 // https://github.com/microsoft/qsharp-compiler/pull/810 logger.LogDebug("Loading serialization and deserialziation protocols."); Protocols.Initialize(); logger.LogDebug("Getting services required to start IQ# engine."); var serviceTasks = new { Snippets = services.GetRequiredServiceInBackground <ISnippets>(logger), SymbolsResolver = services.GetRequiredServiceInBackground <ISymbolResolver>(logger), MagicResolver = services.GetRequiredServiceInBackground <IMagicSymbolResolver>(logger), Workspace = services.GetRequiredServiceInBackground <IWorkspace>(logger), References = services.GetRequiredServiceInBackground <IReferences>(logger) }; this.Snippets = await serviceTasks.Snippets; this.SymbolsResolver = await serviceTasks.SymbolsResolver; this.MagicResolver = await serviceTasks.MagicResolver; this.Workspace = await serviceTasks.Workspace; var references = await serviceTasks.References; logger.LogDebug("Registering IQ# display and JSON encoders."); RegisterDisplayEncoder(new IQSharpSymbolToHtmlResultEncoder()); RegisterDisplayEncoder(new IQSharpSymbolToTextResultEncoder()); RegisterDisplayEncoder(new TaskStatusToTextEncoder()); RegisterDisplayEncoder(new StateVectorToHtmlResultEncoder(configurationSource)); RegisterDisplayEncoder(new StateVectorToTextResultEncoder(configurationSource)); RegisterDisplayEncoder(new DataTableToHtmlEncoder()); RegisterDisplayEncoder(new DataTableToTextEncoder()); RegisterDisplayEncoder(new DisplayableExceptionToHtmlEncoder()); RegisterDisplayEncoder(new DisplayableExceptionToTextEncoder()); RegisterDisplayEncoder(new DisplayableHtmlElementEncoder()); // For back-compat with older versions of qsharp.py <= 0.17.2105.144881 // that expected the application/json MIME type for the JSON data. var userAgentVersion = metadataController.GetUserAgentVersion(); logger.LogInformation($"userAgentVersion: {userAgentVersion}"); var jsonMimeType = metadataController?.UserAgent?.StartsWith("qsharp.py") == true ? userAgentVersion != null && userAgentVersion > new Version(0, 17, 2105, 144881) ? "application/x-qsharp-data" : "application/json" : "application/x-qsharp-data"; // Register JSON encoders, and make sure that Newtonsoft.Json // doesn't throw exceptions on reference loops. JsonConvert.DefaultSettings = () => new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; RegisterJsonEncoder(jsonMimeType, JsonConverters.AllConverters .Concat(AzureClient.JsonConverters.AllConverters) .ToArray()); logger.LogDebug("Registering IQ# symbol resolvers."); RegisterSymbolResolver(this.SymbolsResolver); RegisterSymbolResolver(this.MagicResolver); logger.LogDebug("Loading known assemblies and registering package loading."); RegisterPackageLoadedEvent(services, logger, references); // Handle new shell messages. ShellRouter.RegisterHandlers <IQSharpEngine>(); // Report performance after completing startup. performanceMonitor.Report(); logger.LogInformation( "IQ# engine started successfully as process {Process}.", Process.GetCurrentProcess().Id ); eventService?.TriggerServiceInitialized <IExecutionEngine>(this); var initializedSuccessfully = initializedSource.TrySetResult(true); #if DEBUG Debug.Assert(initializedSuccessfully, "Was unable to complete initialization task."); #endif }