Exemplo n.º 1
0
        public async Task InitializeAsync()
        {
            var(client, server) = await Initialize(new TConfigureClient().Configure, new TConfigureServer().Configure);

            Client = client;
            Server = server;
        }
        protected virtual async Task <(IDebugAdapterClient client, IDebugAdapterServer server)> Initialize(
            Action <DebugAdapterClientOptions> clientOptionsAction,
            Action <DebugAdapterServerOptions> serverOptionsAction
            )
        {
            var clientPipe = new Pipe(TestOptions.DefaultPipeOptions);
            var serverPipe = new Pipe(TestOptions.DefaultPipeOptions);

            _client = DebugAdapterClient.Create(
                options => {
                options
                .WithLoggerFactory(TestOptions.ClientLoggerFactory)
                .ConfigureLogging(
                    x => {
                    x.SetMinimumLevel(LogLevel.Trace);
                    x.Services.AddSingleton(TestOptions.ClientLoggerFactory);
                }
                    )
                .Services
                .AddTransient(typeof(IPipelineBehavior <,>), typeof(SettlePipeline <,>))
                .AddSingleton(ClientEvents as IRequestSettler);
                ConfigureClientInputOutput(serverPipe.Reader, clientPipe.Writer, options);
                clientOptionsAction(options);
            }
                );

            _server = DebugAdapterServer.Create(
                options => {
                options
                .WithLoggerFactory(TestOptions.ServerLoggerFactory)
                .ConfigureLogging(
                    x => {
                    x.SetMinimumLevel(LogLevel.Trace);
                    x.Services.AddSingleton(TestOptions.ServerLoggerFactory);
                }
                    )
                .Services
                .AddTransient(typeof(IPipelineBehavior <,>), typeof(SettlePipeline <,>))
                .AddSingleton(ServerEvents as IRequestSettler);
                ConfigureServerInputOutput(clientPipe.Reader, serverPipe.Writer, options);
                serverOptionsAction(options);
            }
                );

            Disposable.Add(_client);
            Disposable.Add(_server);

            return(await Observable.FromAsync(_client.Initialize).ForkJoin(
                       Observable.FromAsync(_server.Initialize),
                       (a, b) => (_client, _server)
                       ).ToTask(CancellationToken));
        }
        // PSES follows the following flow:
        // Receive a Initialize request
        // Run Initialize handler and send response back
        // Receive a Launch/Attach request
        // Run Launch/Attach handler and send response back
        // PSES sends the initialized event at the end of the Launch/Attach handler

        // The way that the Omnisharp server works is that this OnStarted handler runs after OnInitialized
        // (after the Initialize DAP response is sent to the client) but before the _Initalized_ DAP event
        // gets sent to the client. Because of the way PSES handles breakpoints,
        // we can't send the Initialized event until _after_ we finish the Launch/Attach handler.
        // The flow above depicts this. To achieve this, we wait until _debugStateService.ServerStarted
        // is set, which will be done by the Launch/Attach handlers.
        public async Task OnStarted(IDebugAdapterServer server, CancellationToken cancellationToken)
        {
            // We wait for this task to be finished before triggering the initialized message to
            // be sent to the client.
            await _debugStateService.ServerStarted.Task.ConfigureAwait(false);
        }