From a52ac9b87bc99ea1006334d67f83a70ff736c7ca Mon Sep 17 00:00:00 2001 From: Felipe Orozco Date: Fri, 6 Mar 2020 10:45:47 -0500 Subject: [PATCH] handle uri removal in pin until error update (#497) handle uri removal in pin until error update --- changelog/@unreleased/pr-497.v2.yml | 5 +++++ .../com/palantir/dialogue/core/PinUntilErrorChannel.java | 5 +++++ .../palantir/dialogue/core/PinUntilErrorChannelTest.java | 7 +++++++ 3 files changed, 17 insertions(+) create mode 100644 changelog/@unreleased/pr-497.v2.yml diff --git a/changelog/@unreleased/pr-497.v2.yml b/changelog/@unreleased/pr-497.v2.yml new file mode 100644 index 000000000..e494cd318 --- /dev/null +++ b/changelog/@unreleased/pr-497.v2.yml @@ -0,0 +1,5 @@ +type: fix +fix: + description: handle uri removal in pin until error update + links: + - https://github.com/palantir/dialogue/pull/497 diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/PinUntilErrorChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/PinUntilErrorChannel.java index 0e026a5d6..eeebf068d 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/PinUntilErrorChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/PinUntilErrorChannel.java @@ -75,6 +75,10 @@ final class PinUntilErrorChannel implements LimitedChannel { nodeList.size() >= 2, "PinUntilError is pointless if you have zero or 1 channels." + " Use an always throwing channel or just pick the only channel in the list."); + Preconditions.checkArgument( + 0 <= initialHost && initialHost < nodeList.size(), + "initialHost must be a valid index into nodeList", + SafeArg.of("initialHost", initialHost)); } static PinUntilErrorChannel of( @@ -100,6 +104,7 @@ static PinUntilErrorChannel from( ImmutableList initialShuffle = shuffleImmutableList(channels, random); // We only rely on reference equality since we expect LimitedChannels to be reused across updates int initialHost = initialShuffle.indexOf(initialChannel); + initialHost = initialHost == -1 ? 0 : initialHost; switch (strategy) { case PIN_UNTIL_ERROR: diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/PinUntilErrorChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/PinUntilErrorChannelTest.java index faeb4907c..44641373d 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/PinUntilErrorChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/PinUntilErrorChannelTest.java @@ -27,6 +27,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; +import com.palantir.conjure.java.client.config.NodeSelectionStrategy; import com.palantir.dialogue.Response; import com.palantir.tritium.metrics.registry.DefaultTaggedMetricRegistry; import java.time.Duration; @@ -169,6 +170,12 @@ public void finds_first_non_limited_channel() { assertThat(pinUntilError.maybeExecute(null, null)).isPresent(); } + @Test + void handles_reconstruction_from_stale_state() { + PinUntilErrorChannel.from( + null, NodeSelectionStrategy.PIN_UNTIL_ERROR, ImmutableList.of(channel1, channel2), metrics, pseudo); + } + private static int getCode(PinUntilErrorChannel channel) { try { ListenableFuture future = channel.maybeExecute(null, null).get();