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); }
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); } }
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); }