use of reactor.netty.Connection in project reactor-netty by reactor.
the class TcpClientTests method tcpClientHandlesLineFeedData.
@Test
void tcpClientHandlesLineFeedData() throws InterruptedException {
final int messages = 100;
final CountDownLatch latch = new CountDownLatch(messages);
final List<String> strings = new ArrayList<>();
Connection client = TcpClient.create().host("localhost").port(echoServerPort).doOnConnected(c -> c.addHandlerLast("codec", new LineBasedFrameDecoder(8 * 1024))).handle((in, out) -> out.sendString(Flux.range(1, messages).map(i -> "Hello World!" + i + "\n").subscribeOn(Schedulers.parallel())).then(in.receive().asString().take(100).flatMapIterable(s -> Arrays.asList(s.split("\\n"))).doOnNext(s -> {
strings.add(s);
latch.countDown();
}).then())).wiretap(true).connectNow(Duration.ofSeconds(15));
assertThat(latch.await(15, TimeUnit.SECONDS)).as("Expected messages not received. Received " + strings.size() + " messages: " + strings).isTrue();
assertThat(strings).hasSize(messages);
client.disposeNow();
}
use of reactor.netty.Connection in project reactor-netty by reactor.
the class TcpClientTests method writeIdleDoesNotFireWhileDataIsBeingSent.
@Test
void writeIdleDoesNotFireWhileDataIsBeingSent() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
long start = System.currentTimeMillis();
Connection client = TcpClient.create().host("localhost").port(echoServerPort).handle((in, out) -> {
log.debug("hello");
out.withConnection(c -> c.onWriteIdle(500, latch::countDown));
List<Publisher<Void>> allWrites = new ArrayList<>();
for (int i = 0; i < 5; i++) {
allWrites.add(out.sendString(Flux.just("a").delayElements(Duration.ofMillis(750))));
}
return Flux.merge(allWrites);
}).wiretap(true).connectNow();
log.debug("Started");
assertThat(latch.await(5, TimeUnit.SECONDS)).as("latch await").isTrue();
long duration = System.currentTimeMillis() - start;
assertThat(duration).isGreaterThanOrEqualTo(500L);
client.disposeNow();
}
use of reactor.netty.Connection in project reactor-netty by reactor.
the class TcpClientTests method testIssue585_1.
@Test
void testIssue585_1() throws Exception {
DisposableServer server = TcpServer.create().port(0).handle((req, res) -> res.send(req.receive().retain())).wiretap(true).bindNow();
CountDownLatch latch = new CountDownLatch(1);
byte[] bytes = "test".getBytes(Charset.defaultCharset());
ByteBuf b1 = Unpooled.wrappedBuffer(bytes);
ByteBuf b2 = Unpooled.wrappedBuffer(bytes);
ByteBuf b3 = Unpooled.wrappedBuffer(bytes);
WeakReference<ByteBuf> refCheck1 = new WeakReference<>(b1);
WeakReference<ByteBuf> refCheck2 = new WeakReference<>(b2);
WeakReference<ByteBuf> refCheck3 = new WeakReference<>(b3);
Connection conn = TcpClient.create().remoteAddress(server::address).wiretap(true).connectNow();
NettyOutbound out = conn.outbound();
Flux.concatDelayError(out.sendObject(Mono.error(new RuntimeException("test"))).sendObject(b1).then(), out.sendObject(Mono.error(new RuntimeException("test"))).sendObject(b2).then(), out.sendObject(Mono.error(new RuntimeException("test"))).sendObject(b3).then()).doOnError(t -> latch.countDown()).subscribe(conn.disposeSubscriber());
assertThat(latch.await(30, TimeUnit.SECONDS)).as("latch await").isTrue();
assertThat(b1.refCnt()).isEqualTo(0);
b1 = null;
checkReference(refCheck1);
assertThat(b2.refCnt()).isEqualTo(0);
b2 = null;
checkReference(refCheck2);
assertThat(b3.refCnt()).isEqualTo(0);
b3 = null;
checkReference(refCheck3);
server.disposeNow();
conn.disposeNow();
}
use of reactor.netty.Connection in project reactor-netty by reactor.
the class UdpServerBind method bind.
@Override
public Mono<? extends Connection> bind() {
UdpServerConfig conf = configuration();
ConnectionObserver observer = config.defaultConnectionObserver().then(config.connectionObserver());
Mono<? extends Connection> mono = ConnectionProvider.newConnection().acquire(conf, observer, null, null);
if (conf.doOnBind() != null) {
mono = mono.doOnSubscribe(s -> conf.doOnBind().accept(conf));
}
return mono;
}
use of reactor.netty.Connection in project reactor-netty by reactor.
the class PooledConnectionProvider method acquire.
@Override
public final Mono<? extends Connection> acquire(TransportConfig config, ConnectionObserver connectionObserver, @Nullable Supplier<? extends SocketAddress> remote, @Nullable AddressResolverGroup<?> resolverGroup) {
Objects.requireNonNull(config, "config");
Objects.requireNonNull(connectionObserver, "connectionObserver");
Objects.requireNonNull(remote, "remoteAddress");
Objects.requireNonNull(resolverGroup, "resolverGroup");
return Mono.create(sink -> {
SocketAddress remoteAddress = Objects.requireNonNull(remote.get(), "Remote Address supplier returned null");
PoolKey holder = new PoolKey(remoteAddress, config.channelHash());
PoolFactory<T> poolFactory = poolFactory(remoteAddress);
InstrumentedPool<T> pool = MapUtils.computeIfAbsent(channelPools, holder, poolKey -> {
if (log.isDebugEnabled()) {
log.debug("Creating a new [{}] client pool [{}] for [{}]", name, poolFactory, remoteAddress);
}
InstrumentedPool<T> newPool = createPool(config, poolFactory, remoteAddress, resolverGroup);
if (poolFactory.metricsEnabled || config.metricsRecorder() != null) {
// registrar is null when metrics are enabled on HttpClient level or
// with the `metrics(boolean metricsEnabled)` method on ConnectionProvider
String id = poolKey.hashCode() + "";
if (poolFactory.registrar != null) {
poolFactory.registrar.get().registerMetrics(name, id, remoteAddress, new DelegatingConnectionPoolMetrics(newPool.metrics()));
} else if (Metrics.isInstrumentationAvailable()) {
// work directly with the pool otherwise a weak reference is needed to ConnectionPoolMetrics
// we don't want to keep another map with weak references
registerDefaultMetrics(id, remoteAddress, newPool.metrics());
}
}
return newPool;
});
EventLoop eventLoop = config.loopResources().onClient(config.isPreferNative()).next();
pool.acquire(Duration.ofMillis(poolFactory.pendingAcquireTimeout)).contextWrite(ctx -> ctx.put(CONTEXT_CALLER_EVENTLOOP, eventLoop)).subscribe(createDisposableAcquire(config, connectionObserver, poolFactory.pendingAcquireTimeout, pool, sink));
});
}
Aggregations