int inactivityFactor) { WeightedReconnectingRSocket rSocket = new WeightedReconnectingRSocket( requestHandlingRSocket, destinationNameFactory, inactivityFactor); rSocket.resetStatsProcessor(); rSocket.resetMono(); rSocket.connect();
@Override public Mono<Void> fireAndForget(Payload payload) { return getRSocket() .flatMap( source -> { long start = start(); try { return source .fireAndForget(payload) .doOnCancel(() -> stop(start)) .doOnSuccessOrError( (p, t) -> { long now = stop(start); if (t == null || t instanceof TimeoutException) { record(now - start); } if (t != null) { recordError(0.0); } else { recordError(1.0); } }); } catch (Throwable t) { stop(start); recordError(0.0); return Mono.error(t); } }); }
int inactivityFactor) { WeightedReconnectingRSocket rSocket = new WeightedReconnectingRSocket( requestHandlingRSocket, destinationNameFactory, inactivityFactor); rSocket.resetMono(); rSocket.connect();
@Test public void testShouldEmitNewRSocketAfterSubscribing() throws Exception { CountDownLatch latch = new CountDownLatch(1); WeightedReconnectingRSocket rSocket = new WeightedReconnectingRSocket( Mockito.mock(RSocket.class), Mockito.mock(DestinationNameFactory.class), Mockito.mock(Function.class), () -> true, Mockito.mock(Supplier.class), false, 0, 0, 0, 0, Unpooled.EMPTY_BUFFER, new FrugalQuantile(0.2), new FrugalQuantile(0.6), 1); rSocket.resetMono(); RSocket mock = Mockito.mock(RSocket.class); Mockito.when(mock.onClose()).thenReturn(Mono.never()); rSocket.getRSocket().subscribe(r -> latch.countDown()); rSocket.setRSocket(mock); latch.await(); }
Mono.defer(() -> Mono.delay(calculateRetryDuration())) .then( Mono.defer( return getClientFactory(destination) .errorConsumer( throwable -> connect(); }) .subscribe(); setRSocket(rSocket); }); }))
@Override public Flux<Payload> requestChannel(Publisher<Payload> payloads) { return getRSocket() .flatMapMany( source -> { try { pendingStreams.incrementAndGet(); return source .requestChannel(payloads) .doFinally( s -> { pendingStreams.decrementAndGet(); }) .doOnNext( o -> { recordError(1.0); }) .doOnError( t -> { recordError(0.0); }); } catch (Throwable t) { recordError(0.0); return Flux.error(t); } }); }
Mono.defer(() -> Mono.delay(calculateRetryDuration())) .then( Mono.defer( this.statsProcessor = getStatsProcessor(); String destination = destinationNameFactory.get(); return getClientFactory(destination) .errorConsumer( throwable -> resetStatsProcessor(); availability = 0.0; synchronized (WeightedReconnectingRSocket.this) { connect(); }) .subscribe(); setRSocket(rSocket); }); }))
void setRSocket(RSocket rSocket) { MonoProcessor<RSocket> _m; synchronized (this) { _m = currentSink; resetStatistics(); } _m.onNext(rSocket); _m.onComplete(); Disposable subscribe = onClose .doFinally( s -> { rSocket.dispose(); _m.cancel(); }) .subscribe(); rSocket .onClose() .doFinally( s -> { subscribe.dispose(); resetMono(); }) .subscribe(); }
@Test public void testShouldWaitForSocketWhenNotPresent() { WeightedReconnectingRSocket rSocket = new WeightedReconnectingRSocket( Mockito.mock(RSocket.class), Mockito.mock(DestinationNameFactory.class), Mockito.mock(Function.class), () -> true, Mockito.mock(Supplier.class), false, 0, 0, 0, 0, Unpooled.EMPTY_BUFFER, new FrugalQuantile(0.2), new FrugalQuantile(0.6), 1); rSocket.resetMono(); StepVerifier.create(rSocket.getRSocket()) .expectNextCount(0) .thenCancel() .verify(Duration.ofSeconds(1)); }
@Override public synchronized double predictedLatency() { long now = Clock.now(); long elapsed = Math.max(now - stamp, 1L); double weight; double prediction = median.estimation(); if (prediction == 0.0) { if (pending == 0) { weight = 0.0; // first request } else { // subsequent requests while we don't have any history weight = STARTUP_PENALTY + pending; } } else if (pending == 0 && elapsed > inactivityFactor * interArrivalTime.value()) { // if we did't see any data for a while, we decay the prediction by inserting // artificial 0.0 into the median median.insert(0.0); weight = median.estimation(); } else { double predicted = prediction * pending; double instant = instantaneous(now); if (predicted < instant) { // NB: (0.0 < 0.0) == false weight = instant / pending; // NB: pending never equal 0 here } else { // we are under the predictions weight = prediction; } } return weight; }
if (rsc1.availability() > 0.0 && rsc2.availability() > 0.0) { break;
WeightedReconnectingRSocket rSocket = Mockito.spy( new WeightedReconnectingRSocket( Mockito.mock(RSocket.class), Mockito.mock(DestinationNameFactory.class), 1)); rSocket.resetMono(); rSocket.setRSocket(mock); StepVerifier.create(rSocket.getRSocket()) .expectNextMatches(Predicate.isEqual(mock)) .verifyComplete(); Mockito.verify(rSocket, Mockito.times(1)).resetStatistics(); rSocket.resetMono(); rSocket.setRSocket(mock2); StepVerifier.create(rSocket.getRSocket()) .expectNextMatches(Predicate.isEqual(mock2)) .verifyComplete();
Mono.defer(() -> Mono.delay(calculateRetryDuration())) .then( Mono.defer( return getClientFactory(setupPayload) .errorConsumer( throwable -> connect(); }) .subscribe(); setRSocket(rSocket); }) .doFinally(signalType -> setupPayload.release());
@Override public Flux<Payload> requestStream(Payload payload) { return getRSocket() .flatMapMany( source -> { try { pendingStreams.incrementAndGet(); return source .requestStream(payload) .doFinally( s -> { pendingStreams.decrementAndGet(); }) .doOnNext( o -> { recordError(1.0); }) .doOnError( t -> { recordError(0.0); }); } catch (Throwable t) { recordError(0.0); return Flux.error(t); } }); }
int inactivityFactor) { WeightedReconnectingRSocket rSocket = new WeightedReconnectingRSocket( requestHandlingRSocket, destinationNameFactory, inactivityFactor); rSocket.resetMono(); rSocket.connect();
void setRSocket(RSocket rSocket) { MonoProcessor<RSocket> _m; synchronized (this) { _m = currentSink; resetStatistics(); } _m.onNext(rSocket); _m.onComplete(); Disposable subscribe = onClose .doFinally( s -> { rSocket.dispose(); _m.cancel(); }) .subscribe(); rSocket .onClose() .doFinally( s -> { subscribe.dispose(); resetMono(); }) .subscribe(); }
@Override public synchronized double predictedLatency() { long now = Clock.now(); long elapsed = Math.max(now - stamp, 1L); double weight; double prediction = median.estimation(); if (prediction == 0.0) { if (pending == 0) { weight = 0.0; // first request } else { // subsequent requests while we don't have any history weight = STARTUP_PENALTY + pending; } } else if (pending == 0 && elapsed > inactivityFactor * interArrivalTime.value()) { // if we did't see any data for a while, we decay the prediction by inserting // artificial 0.0 into the median median.insert(0.0); weight = median.estimation(); } else { double predicted = prediction * pending; double instant = instantaneous(now); if (predicted < instant) { // NB: (0.0 < 0.0) == false weight = instant / pending; // NB: pending never equal 0 here } else { // we are under the predictions weight = prediction; } } return weight; }
if (rsc1.availability() > 0.0 && rsc2.availability() > 0.0) { break;
@Override public Mono<Payload> requestResponse(Payload payload) { return getRSocket() .flatMap( source -> { long start = start(); try { return source .requestResponse(payload) .doOnCancel(() -> stop(start)) .doOnSuccessOrError( (p, t) -> { long now = stop(start); if (t == null || t instanceof TimeoutException) { record(now - start); } if (t != null) { recordError(0.0); } else { recordError(1.0); } }); } catch (Throwable t) { stop(start); recordError(0.0); return Mono.error(t); } }); }
new WeightedReconnectingRSocket( Mockito.mock(RSocket.class), Mockito.mock(DestinationNameFactory.class), 1); rSocket.resetMono(); Mockito.when(mock.onClose()).thenReturn(processor); rSocket.setRSocket(mock); StepVerifier.create(rSocket.getRSocket()) .expectNextCount(0) .thenCancel()