Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/DiffEngineViewer.Tests/AttachedViewerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,33 @@ public async Task ABusyOwnerDoesNotReadAsDead()
_ = listening;
}

/// <summary>
/// An owner that answers is an owner, whatever it answered.
/// <para>
/// ViewerServer turns any exception in the listing handler into an error reply, and this side
/// read one of those as the owner having gone: the window closed with "The queue owner is no
/// longer running." over a single transient throw, taking the queue it was displaying with it.
/// </para>
/// </summary>
[Test]
public async Task AnErrorReplyIsNotADeadOwner()
{
await Assert.That(ViewerServer.TryBind(0, out var bound)).IsTrue();
using var server = bound!;
using var cancel = new CancelSource();
var listening = server.Listen(
_ => ViewerResponse.Error("The listing could not be built"),
cancel.Token);
var host = new SessionHost(SessionState.Start(ViewerMode.Inline, Fixtures.Columns, Fixtures.Rows));

await Assert.That(new OwnerLink(host, server.Port).Pump()).IsTrue();

await Assert.That(host.State.Message).IsEqualTo("The listing could not be built");
await Assert.That(host.State.Exit).IsFalse();
await cancel.CancelAsync();
_ = listening;
}

/// <summary>
/// The owner has no window of its own, so raising, hiding and closing come back on a listing
/// rather than being pushed at a port this process does not hold.
Expand Down
16 changes: 14 additions & 2 deletions src/DiffEngineViewer/Ipc/OwnerLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,24 @@ public bool Pump(out bool sent)
message = Send(command);
}

if (!ViewerClient.TrySend(new(ViewerVerb.ListFull), out var response, port, Wait) ||
!response.Ok)
if (!ViewerClient.TrySend(new(ViewerVerb.ListFull), out var response, port, Wait))
{
return false;
}

if (!response.Ok)
{
// An owner that answers is an owner. ViewerServer turns any exception in the listing
// handler into an error reply, so reading one as death closed this window over a
// single transient throw and lost the queue it was displaying. Said instead, and asked
// again on the next pass.
host.Mutate(_ => _ with
{
Message = response.Message ?? "The queue owner refused the listing."
});
return true;
}

var pending = InlineQueue.From(ViewerListing.Pending(response.Items));
var changes = ReadChanges(response);
host.Mutate(_ => ViewerSession.Sync(_, pending, changes, message));
Expand Down
Loading