CompositeDelayFunction implements DelayFunction<R, X> { @Override public Duration computeDelay(final R result, final X failure, final ExecutionContext context) { return functions.stream() .map(function -> function.computeDelay(result, failure, context)) .filter(Objects::nonNull) .findFirst() .orElse(null); }  @Override Duration computeDelay(final R result, final X failure, final ExecutionContext context); @SafeVarargs static DelayFunction<R, X> composite(
            final DelayFunction<R, X>... functions);  }
@Test void shouldUseFirstNonNullDelay() { when(first.computeDelay(eq("1"), any(), any())).thenReturn(Duration.ofSeconds(1)); when(second.computeDelay(eq("2"), any(), any())).thenReturn(Duration.ofSeconds(2)); assertEquals(Duration.ofSeconds(1), unit.computeDelay("1", null, null)); }
@Test void shouldIgnoreNullDelay() { when(second.computeDelay(eq("2"), any(), any())).thenReturn(Duration.ofSeconds(2)); assertEquals(Duration.ofSeconds(2), unit.computeDelay("2", null, null)); }
@Test void shouldFallbackToNullDelay() { when(first.computeDelay(eq("1"), any(), any())).thenReturn(Duration.ofSeconds(1)); when(second.computeDelay(eq("2"), any(), any())).thenReturn(Duration.ofSeconds(2)); assertNull(unit.computeDelay("3", null, null)); }