Şöyle yaparız
webClient.get().uri("/endpoint").retrieve().bodyToMono(String.class).timeout(Duration.ofSeconds(10));
webClient.get().uri("/endpoint").retrieve().bodyToMono(String.class).timeout(Duration.ofSeconds(10));
this.retryBackoffSpec = Retry.backoff(maxAttempts, Duration.ofSeconds(backoffSeconds)).doBeforeRetry(retrySignal -> log.debug("Waiting {} seconds. Retry #{} of {} after exception: {}", backoffSeconds, (retrySignal.totalRetriesInARow()+1), maxAttempts, retrySignal.failure().getLocalizedMessage() )) .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> retrySignal.failure()); this.webClient.post().uri(uri) .bodyValue(emailText) .retrieve() … .bodyToMono(CtfdUserResponse.class) .retryWhen(retryBackoffSpec) .block();
WebClient webClient = WebClient.builder().baseUrl("http://example.com").build();Mono<String> response = webClient.get().uri("/retry-endpoint").retrieve().bodyToMono(String.class)// number of retries and backoff configuration.retryWhen(Retry.backoff(3, Duration.ofSeconds(1))// maximum backoff time.maxBackoff(Duration.ofSeconds(10)))// fallback if retries all fail.onErrorResume(e -> Mono.just("Fallback response"));response.subscribe(result -> System.out.println(result));
Predicate<Throwable> exceptionFilter() {
return throwable -> throwable instanceof RuntimeException
|| (throwable instanceof WebClientResponseException
&& (throwable.getStatusCode() == HttpStatus.GATEWAY_TIMEOUT
|| throwable.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE
|| throwable.getStatusCode() == HttpStatus.BAD_GATEWAY));
}
Retry retry = Retry.backoff(3, Duration.ofSeconds(2))
.jitter(0.7)
.filter(exceptionFilter())
.onRetryExhaustedThrow((retrySpec, retrySignal) -> {
log.error("Service at {} failed to respond, after max attempts of: {}",
uri, retrySignal.totalRetries());
return retrySignal.failure();
});Log çıktısı şöyledirreturn Mono.fromCallable(() ->getHttpBlocking("https://www.google.com")).subscribeOn(Schedulers.boundedElastic())
{"@timestamp":"2021-06-07T07:42:49.709-04:00","@version":"1","message":"querying google","logger_name":"net.kamradtfamily.blockingnono.Controller","thread_name":"reactor-http-nio-3","level":"INFO","level_value":20000}{"@timestamp":"2021-06-07T07:42:49.939-04:00","@version":"1","message":"found content length 12991","logger_name":"net.kamradtfamily.blockingnono.Controller","thread_name":"boundedElastic-1","level":"INFO","level_value":20000}
Log şöyledir. Burada Mono.just() çağrısının thread değiştirmediği görülebilir.@Slf4j@RestController@RequestMapping("/")public class Controller {RestTemplate restTemplate = new RestTemplate();@GetMapping("/blocking")public Mono<String> getFiles() {log.info("querying google");return Mono.just(getHttpBlocking("https://www.google.com")).doOnNext(s ->log.info("found content length {}", s.length()));}String getHttpBlocking(String url) {return restTemplate.getForObject(url, String.class);}}
{"@timestamp":"2021-06-07T07:05:57.225-04:00","@version":"1","message":"querying google","logger_name":"net.kamradtfamily.blockingnono.Controller","thread_name":"reactor-http-nio-3","level":"INFO","level_value":20000}{"@timestamp":"2021-06-07T07:05:57.640-04:00","@version":"1","message":"found content length 12962","logger_name":"net.kamradtfamily.blockingnono.Controller","thread_name":"reactor-http-nio-3","level":"INFO","level_value":20000}
we can emit an error signal when our mono has no values to emit.
Mono<String> publisher = Mono.just("My first publisher");publisher.filter(value -> value.equals("This is not my first publisher")).switchIfEmpty(Mono.error(new RuntimeException("Something went wrong"))).subscribe(new MySubscriber());
Mono.just(new Employee().setName("Kill"))
.switchIfEmpty(Mono.defer(() -> Mono.just(new Employee("Bill"))))
.block()
.getName();ÖrnekŞöyle yaparız. @RestController@RequestMapping(value = "/posts")class PostController { private final PostRepository posts;
@GetMapping("/{id}") public Mono<Post> get(@PathVariable("id") Long id) { return Mono.just(id) .flatMap(posts::findById) .switchIfEmpty(Mono.error(new PostNotFoundException(id))); }}
import reactor.core.publisher.Mono;
Reactor on the other hand is Java 8+ only, so it can make full use of the new Java 8 native classes. Since Spring 5.0 is also Java 8+ only, that means Reactor has the edge in this regard.Bu Sınıf Niçin Lazım ?
The Reactive Streams types are not enough; you’ll need higher order implementations to support operations like filtering and transformation. The Reactor project is a good choice here; it builds on top of the Reactive Streams specification. It provides two specializations of Publisher<T>.block metodu
The first, Flux<T>, is a Publisher that produces zero or more values. It’s unbounded. The second, Mono<T>, is a Publisher<T> that produces zero or one value. They’re both publishers and you can treat them that way, but they go much further than the Reactive Streams specification. They both provide operators, ways to process a stream of values. Reactor types compose nicely - the output of one thing can be the input to another and if a type needs to work with other streams of data, they rely upon Publisher<T> instances.
Both Mono<T> and Flux<T> implement Publisher<T>; our recommendation is that your methods accept Publisher<T> instances but return Flux<T> or Mono<T> to help the client distinguish the kind of data its being given.
to retrieve object from mono you have to blockÖrnek
Mono.just(new Employee().setName("Kill"))
.switchIfEmpty(Mono.defer(() -> Mono.just(new Employee("Bill"))))
.block()
.getName();
doOnError metodu - ConsumerMono<AuthorizeResponse> result = ...
response = result.doOnError(e -> {throw new RuntimeException(e);})
.block();
@Transactionalpublic Mono<Store> addStore(Store store) {if (store.isValid()) {final Mono<Store> result = storePort.addStore(store);return result;}return Mono.error(InvalidAttributesException::new);}
fromSupplier metoduMono.fromRunnable(() -> System.out.println("Hello")).subscribe(i -> System.out.println("Received :: " + i),err -> System.out.println("Error :: " + err),() -> System.out.println("Successfully completed"));//OutputHelloSuccessfully completed
public Mono<Integer> nonBlockingSum(Integer arr[])
throws InterruptedException {
Mono<Integer> m = Mono.fromSupplier(() ->this.computationService.getSum(arr))
.subscribeOn(this.scheduler);
return m;
}
Mono<String> publisher = Mono.justOrEmpy("My first publisher");