Esempio n. 1
0
        public async Task UpdatePayload_CanRoundTrip()
        {
            var initial = new UpdatePayload
            {
                ChangedFile = "Some-file",
                Deltas      = new[]
                {
                    new UpdateDelta
                    {
                        ModuleId      = Guid.NewGuid(),
                        ILDelta       = new byte[] { 0, 0, 1 },
                        MetadataDelta = new byte[] { 0, 1, 1 },
                    },
                    new UpdateDelta
                    {
                        ModuleId      = Guid.NewGuid(),
                        ILDelta       = new byte[] { 1, 0, 0 },
                        MetadataDelta = new byte[] { 1, 0, 1 },
                    }
                },
            };

            using var stream = new MemoryStream();
            await initial.WriteAsync(stream, default);

            stream.Position = 0;
            var read = await UpdatePayload.ReadAsync(stream, default);

            AssertEqual(initial, read);
        }
Esempio n. 2
0
        private static void AssertEqual(UpdatePayload initial, UpdatePayload read)
        {
            Assert.Equal(initial.ChangedFile, read.ChangedFile);
            Assert.Equal(initial.Deltas.Count, read.Deltas.Count);

            for (var i = 0; i < initial.Deltas.Count; i++)
            {
                var e = initial.Deltas[i];
                var a = read.Deltas[i];

                Assert.Equal(e.ModuleId, a.ModuleId);
                Assert.Equal(e.ILDelta, a.ILDelta);
                Assert.Equal(e.MetadataDelta, a.MetadataDelta);
            }
        }
Esempio n. 3
0
        public async Task UpdatePayload_WithLargeDeltas_CanRoundtrip()
        {
            var initial = new UpdatePayload
            {
                ChangedFile = "Some-file",
                Deltas      = new[]
                {
                    new UpdateDelta
                    {
                        ModuleId      = Guid.NewGuid(),
                        ILDelta       = Enumerable.Range(0, 68200).Select(c => (byte)(c % 2)).ToArray(),
                        MetadataDelta = new byte[] { 0, 1, 1 },
                    },
                },
            };

            using var stream = new MemoryStream();
            await initial.WriteAsync(stream, default);

            stream.Position = 0;
            var read = await UpdatePayload.ReadAsync(stream, default);

            AssertEqual(initial, read);
        }
        public async ValueTask <bool> Apply(DotNetWatchContext context, string changedFile, DotNetWatchManagedModuleUpdatesWrapper?updates, CancellationToken cancellationToken)
        {
            if (!_task.IsCompletedSuccessfully || !_pipe.IsConnected)
            {
                // The client isn't listening
                _reporter.Verbose("No client connected to receive delta updates.");
                return(false);
            }

            if (updates is null)
            {
                await context.BrowserRefreshServer.SendJsonSerlialized(new HotReloadApplied());

                return(true);
            }

            var payload = new UpdatePayload
            {
                ChangedFile = changedFile,
                Deltas      = ImmutableArray.CreateRange(updates.Value.Updates, c => new UpdateDelta
                {
                    ModuleId      = c.Module,
                    ILDelta       = c.ILDelta.ToArray(),
                    MetadataDelta = c.MetadataDelta.ToArray(),
                }),
            };

            await payload.WriteAsync(_pipe, cancellationToken);

            await _pipe.FlushAsync(cancellationToken);

            var result = ApplyResult.Failed;
            var bytes  = ArrayPool <byte> .Shared.Rent(1);

            try
            {
                var timeout =
#if DEBUG
                    Timeout.InfiniteTimeSpan;
#else
                    TimeSpan.FromSeconds(5);
#endif

                using var cancellationTokenSource = new CancellationTokenSource(timeout);
                var numBytes = await _pipe.ReadAsync(bytes, cancellationTokenSource.Token);

                if (numBytes == 1)
                {
                    result = (ApplyResult)bytes[0];
                }
            }
            catch (Exception ex)
            {
                // Log it, but we'll treat this as a failed apply.
                _reporter.Verbose(ex.Message);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(bytes);
            }

            if (result == ApplyResult.Failed)
            {
                return(false);
            }

            if (context.BrowserRefreshServer != null)
            {
                if (result == ApplyResult.Success_RefreshBrowser)
                {
                    await context.BrowserRefreshServer.ReloadAsync(cancellationToken);
                }
                else if (result == ApplyResult.Success)
                {
                    await context.BrowserRefreshServer.SendJsonSerlialized(new HotReloadApplied());
                }
            }

            return(true);
        }