Example #1
0
    public static async Task ReceiveDeltas(HotReloadAgent hotReloadAgent)
    {
        Log("Attempting to receive deltas.");

        // This value is configured by dotnet-watch when the app is to be launched.
        var namedPipeName = Environment.GetEnvironmentVariable("DOTNET_HOTRELOAD_NAMEDPIPE_NAME") ??
                            throw new InvalidOperationException("DOTNET_HOTRELOAD_NAMEDPIPE_NAME was not specified.");

        using var pipeClient = new NamedPipeClientStream(".", namedPipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
        try
        {
            await pipeClient.ConnectAsync(5000);

            Log("Connected.");
        }
        catch (TimeoutException)
        {
            Log("Unable to connect to hot-reload server.");
            return;
        }

        var initPayload = new ClientInitializationPayload {
            Capabilities = GetApplyUpdateCapabilities()
        };

        Log("Writing capabilities: " + initPayload.Capabilities);
        initPayload.Write(pipeClient);

        while (pipeClient.IsConnected)
        {
            var update = await UpdatePayload.ReadAsync(pipeClient, default);

            Log("Attempting to apply deltas.");

            hotReloadAgent.ApplyDeltas(update.Deltas);
            pipeClient.WriteByte((byte)ApplyResult.Success);
        }
        Log("Stopped received delta updates. Server is no longer connected.");
    }
Example #2
0
        public ValueTask InitializeAsync(DotNetWatchContext context, CancellationToken cancellationToken)
        {
            if (!SuppressNamedPipeForTests)
            {
                _pipe           = new NamedPipeServerStream(_namedPipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);
                _connectionTask = _pipe.WaitForConnectionAsync(cancellationToken);

                _capabilities = Task.Run(async() =>
                {
                    try
                    {
                        await _connectionTask;
                        // When the client connects, the first payload it sends is the initialization payload which includes the apply capabilities.
                        var capabiltiies = ClientInitializationPayload.Read(_pipe).Capabilities;
                        _reporter.Verbose($"Application supports the following capabilities {capabiltiies}.");
                        return(capabiltiies.Split(' ').ToImmutableArray());
                    }
                    catch
                    {
                        // Do nothing. This is awaited by Apply which will surface the error.
                    }

                    return(ImmutableArray <string> .Empty);
                });
            }

            if (context.Iteration == 0)
            {
                var deltaApplier = Path.Combine(AppContext.BaseDirectory, "hotreload", "Microsoft.Extensions.DotNetDeltaApplier.dll");
                context.ProcessSpec.EnvironmentVariables.DotNetStartupHooks.Add(deltaApplier);

                // Configure the app for EnC
                context.ProcessSpec.EnvironmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"]    = "debug";
                context.ProcessSpec.EnvironmentVariables["DOTNET_HOTRELOAD_NAMEDPIPE_NAME"] = _namedPipeName;
            }
            return(default);