chore: Make use of japi.funtion.* in Patterns (#2198)

This commit is contained in:
He-Pin(kerr) 2025-09-13 15:45:20 +08:00 committed by GitHub
parent f48ec1d425
commit 0f6def662f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 84 additions and 9 deletions

View file

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pekko.japi.function;
/**
* Int function that can throw exceptions.
*
* @since 2.0.0
*/
@FunctionalInterface
public interface IntFunction<R> extends java.io.Serializable {
long serialVersionUID = 1L;
/**
* Applies this function to the given argument.
*
* @param value the function argument
* @return the function result
* @throws Throwable if an error occurs
*/
R apply(int value) throws Throwable;
}

View file

@ -0,0 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** Java API for functional programming in Pekko. */
package org.apache.pekko.japi.function;

View file

@ -35,4 +35,5 @@ ProblemFilters.exclude[MissingClassProblem]("org.apache.pekko.japi.Predicate")
ProblemFilters.exclude[MissingClassProblem]("org.apache.pekko.japi.Procedure")
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.apache.pekko.pattern.Patterns.askWithReplyTo")
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.apache.pekko.serialization.SerializationSetup.create")
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.apache.pekko.pattern.Patterns.retry")

View file

@ -15,7 +15,6 @@ package org.apache.pekko.pattern
import java.util.Optional
import java.util.concurrent.{ Callable, CompletionStage, TimeUnit }
import java.util.function.BiPredicate
import scala.concurrent.ExecutionContext
@ -518,7 +517,7 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
ec: ExecutionContext): CompletionStage[T] = {
require(attempt != null, "Parameter attempt should not be null.")
@ -585,7 +584,7 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
minBackoff: java.time.Duration,
maxBackoff: java.time.Duration,
@ -662,7 +661,7 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
minBackoff: java.time.Duration,
maxBackoff: java.time.Duration,
@ -738,7 +737,7 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
delay: java.time.Duration,
system: ClassicActorSystemProvider): CompletionStage[T] =
@ -787,7 +786,7 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
delay: java.time.Duration,
scheduler: Scheduler,
@ -813,7 +812,7 @@ object Patterns {
def retry[T](
attempt: Callable[CompletionStage[T]],
attempts: Int,
delayFunction: java.util.function.IntFunction[Optional[java.time.Duration]],
delayFunction: japi.function.IntFunction[Optional[java.time.Duration]],
scheduler: Scheduler,
context: ExecutionContext): CompletionStage[T] = {
import pekko.util.OptionConverters._
@ -852,9 +851,9 @@ object Patterns {
*/
def retry[T](
attempt: Callable[CompletionStage[T]],
shouldRetry: BiPredicate[T, Throwable],
shouldRetry: japi.function.Predicate2[T, Throwable],
attempts: Int,
delayFunction: java.util.function.IntFunction[Optional[java.time.Duration]],
delayFunction: japi.function.IntFunction[Optional[java.time.Duration]],
scheduler: Scheduler,
context: ExecutionContext): CompletionStage[T] = {
import pekko.util.OptionConverters._

View file

@ -24,6 +24,7 @@ import org.junit.Test;
import java.time.Duration;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@ -97,4 +98,22 @@ public class FutureDocTest extends AbstractJavaTest {
retriedFuture.toCompletableFuture().get(2, SECONDS);
}
@Test
public void useRetryWithPredicateWithIntFunction() throws Exception {
// #retry
Callable<CompletionStage<String>> attempt = () -> CompletableFuture.completedFuture("test");
CompletionStage<String> retriedFuture =
Patterns.retry(
attempt,
(notUsed, e) -> e != null,
3,
current -> Optional.of(java.time.Duration.ofMillis(200)),
system.classicSystem().scheduler(),
system.executionContext());
// #retry
retriedFuture.toCompletableFuture().get(2, SECONDS);
}
}