Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions rsocket-core/src/main/java/io/rsocket/RSocketClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@

package io.rsocket;

import static io.rsocket.util.ExceptionUtil.noStacktrace;

import io.netty.buffer.Unpooled;
import io.netty.util.collection.IntObjectHashMap;
import io.rsocket.exceptions.ConnectionException;
import io.rsocket.exceptions.Exceptions;
import io.rsocket.internal.LimitableRequestPublisher;
import io.rsocket.internal.UnboundedProcessor;
import io.rsocket.util.PayloadImpl;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import reactor.core.Disposable;
import reactor.core.publisher.*;

import javax.annotation.Nullable;
import java.nio.channels.ClosedChannelException;
import java.time.Duration;
import java.util.Collection;
Expand All @@ -37,8 +33,11 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import static io.rsocket.util.ExceptionUtil.noStacktrace;
import javax.annotation.Nullable;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import reactor.core.Disposable;
import reactor.core.publisher.*;

/** Client Side of a RSocket socket. Sends {@link Frame}s to a {@link RSocketServer} */
class RSocketClient implements RSocket {
Expand Down Expand Up @@ -99,7 +98,7 @@ class RSocketClient implements RSocket {
})
.subscribe();
}

connection
.onClose()
.doFinally(
Expand Down
15 changes: 7 additions & 8 deletions rsocket-core/src/main/java/io/rsocket/RSocketServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@

package io.rsocket;

import static io.rsocket.Frame.Request.initialRequestN;
import static io.rsocket.frame.FrameHeaderFlyweight.FLAGS_C;
import static io.rsocket.frame.FrameHeaderFlyweight.FLAGS_M;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.collection.IntObjectHashMap;
import io.rsocket.exceptions.ApplicationException;
import io.rsocket.internal.LimitableRequestPublisher;
import io.rsocket.internal.UnboundedProcessor;
import io.rsocket.util.PayloadImpl;
import java.util.Collection;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
Expand All @@ -32,14 +39,6 @@
import reactor.core.publisher.SignalType;
import reactor.core.publisher.UnicastProcessor;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.function.Consumer;

import static io.rsocket.Frame.Request.initialRequestN;
import static io.rsocket.frame.FrameHeaderFlyweight.FLAGS_C;
import static io.rsocket.frame.FrameHeaderFlyweight.FLAGS_M;

/** Server side RSocket. Receives {@link Frame}s from a {@link RSocketClient} */
class RSocketServer implements RSocket {

Expand Down
121 changes: 60 additions & 61 deletions rsocket-core/src/main/java/io/rsocket/internal/SwitchTransform.java
Original file line number Diff line number Diff line change
@@ -1,81 +1,80 @@
package io.rsocket.internal;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.BiFunction;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscription;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.DirectProcessor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Operators;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.BiFunction;

public final class SwitchTransform<T, R> extends Flux<R> {

final Publisher<? extends T> source;
final BiFunction<T, Flux<T>, Publisher<? extends R>> transformer;

public SwitchTransform(Publisher<? extends T> source, BiFunction<T, Flux<T>, Publisher<? extends R>> transformer) {
this.source = Objects.requireNonNull(source, "source");
this.transformer = Objects.requireNonNull(transformer, "transformer");
}

@Override
public void subscribe(CoreSubscriber<? super R> actual) {
source.subscribe(new SwitchTransformSubscriber<>(actual, transformer));
}
final Publisher<? extends T> source;
final BiFunction<T, Flux<T>, Publisher<? extends R>> transformer;

static final class SwitchTransformSubscriber<T, R> implements CoreSubscriber<T> {
final CoreSubscriber<? super R> actual;
final BiFunction<T, Flux<T>, Publisher<? extends R>> transformer;
final DirectProcessor<T> processor = DirectProcessor.create();
public SwitchTransform(
Publisher<? extends T> source, BiFunction<T, Flux<T>, Publisher<? extends R>> transformer) {
this.source = Objects.requireNonNull(source, "source");
this.transformer = Objects.requireNonNull(transformer, "transformer");
}

Subscription s;
@Override
public void subscribe(CoreSubscriber<? super R> actual) {
Flux.from(source).subscribe(new SwitchTransformSubscriber<>(actual, transformer));
}

volatile int once;
@SuppressWarnings("rawtypes")
static final AtomicIntegerFieldUpdater<SwitchTransformSubscriber> ONCE =
AtomicIntegerFieldUpdater.newUpdater(SwitchTransformSubscriber.class, "once");
static final class SwitchTransformSubscriber<T, R> implements CoreSubscriber<T> {
@SuppressWarnings("rawtypes")
static final AtomicIntegerFieldUpdater<SwitchTransformSubscriber> ONCE =
AtomicIntegerFieldUpdater.newUpdater(SwitchTransformSubscriber.class, "once");

SwitchTransformSubscriber(CoreSubscriber<? super R> actual, BiFunction<T, Flux<T>, Publisher<? extends R>> transformer) {
this.actual = actual;
this.transformer = transformer;
}
final CoreSubscriber<? super R> actual;
final BiFunction<T, Flux<T>, Publisher<? extends R>> transformer;
final UnboundedProcessor<T> processor = new UnboundedProcessor<>();
Subscription s;
volatile int once;

@Override
public void onSubscribe(Subscription s) {
if (Operators.validate(this.s, s)) {
this.s = s;
SwitchTransformSubscriber(
CoreSubscriber<? super R> actual,
BiFunction<T, Flux<T>, Publisher<? extends R>> transformer) {
this.actual = actual;
this.transformer = transformer;
}

processor.onSubscribe(s);
}
}
@Override
public void onSubscribe(Subscription s) {
if (Operators.validate(this.s, s)) {
this.s = s;
processor.onSubscribe(s);
}
}

@Override
public void onNext(T t) {
if (once == 0 && ONCE.compareAndSet(this, 0, 1)) {
try {
Publisher<? extends R> result = Objects.requireNonNull(transformer.apply(t, processor),
"The transformer returned a null value");
result.subscribe(actual);
}
catch (Throwable e) {
onError(Operators.onOperatorError(s, e, t, actual.currentContext()));
return;
}
}
processor.onNext(t);
}
@Override
public void onNext(T t) {
if (once == 0 && ONCE.compareAndSet(this, 0, 1)) {
try {
Publisher<? extends R> result =
Objects.requireNonNull(
transformer.apply(t, processor), "The transformer returned a null value");
Flux.from(result).subscribe(actual);
} catch (Throwable e) {
onError(Operators.onOperatorError(s, e, t, actual.currentContext()));
return;
}
}
processor.onNext(t);
}

@Override
public void onError(Throwable t) {
processor.onError(t);
}
@Override
public void onError(Throwable t) {
processor.onError(t);
}

@Override
public void onComplete() {
processor.onComplete();
}
}
@Override
public void onComplete() {
processor.onComplete();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
package io.rsocket.internal;

import io.netty.util.internal.shaded.org.jctools.queues.atomic.MpscGrowableAtomicArrayQueue;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.CoreSubscriber;
Expand All @@ -27,11 +31,6 @@
import reactor.util.concurrent.Queues;
import reactor.util.context.Context;

import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;

/**
* A Processor implementation that takes a custom queue and allows only a single subscriber.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package io.rsocket.internal;

import java.util.concurrent.CountDownLatch;
import org.junit.Assert;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;

public class UnboundedProcessorTest {
@Test
public void testOnNextBeforeSubscribe_10() {
Expand Down Expand Up @@ -49,39 +48,34 @@ public void testOnNextBeforeSubscribeN(int n) {

Assert.assertEquals(n, count);
}

@Test
public void testOnNextAfterSubscribe_10() throws Exception {
testOnNextAfterSubscribeN(10);
}

@Test
public void testOnNextAfterSubscribe_100() throws Exception {
testOnNextAfterSubscribeN(100);
}

@Test
public void testOnNextAfterSubscribe_1000() throws Exception {
testOnNextAfterSubscribeN(1000);
}
public void testOnNextAfterSubscribeN(int n) throws Exception {

public void testOnNextAfterSubscribeN(int n) throws Exception {
CountDownLatch latch = new CountDownLatch(n);
UnboundedProcessor<Integer> processor = new UnboundedProcessor<>();
processor
.log()
.doOnNext(integer ->
latch.countDown())
.subscribe();

UnboundedProcessor<Integer> processor = new UnboundedProcessor<>();
processor.log().doOnNext(integer -> latch.countDown()).subscribe();

for (int i = 0; i < n; i++) {
System.out.println("onNexting -> " + i);
processor.onNext(i);
}

processor.drain();

latch.await();
}

}
Loading