A non-blocking HTTP client implementation for AWS SDK Java applications using Netty framework, enabling efficient network communication with AWS services through asynchronous I/O operations
Event loop and channel factory management for efficient resource sharing and lifecycle control across multiple HTTP clients using Netty's EventLoopGroup infrastructure.
Wrapper for Netty EventLoopGroup that provides EventLoopGroup and ChannelFactory instances for the NettyNioAsyncHttpClient. Supports both managed (SDK-controlled) and unmanaged (caller-controlled) lifecycle patterns.
/**
* SdkEventLoopGroup provides EventLoopGroup and ChannelFactory management for NettyNioAsyncHttpClient.
* Supports both managed lifecycle (created by SDK) and unmanaged lifecycle (provided by caller).
*/
public final class SdkEventLoopGroup {
/**
* Returns the underlying Netty EventLoopGroup
* @return the EventLoopGroup instance for handling I/O operations
*/
public EventLoopGroup eventLoopGroup();
/**
* Returns the socket channel factory for creating connections
* @return ChannelFactory for socket channels
*/
public ChannelFactory<? extends Channel> channelFactory();
/**
* Returns the datagram channel factory for UDP operations
* @return ChannelFactory for datagram channels
*/
public ChannelFactory<? extends DatagramChannel> datagramChannelFactory();
/**
* Creates a new builder for configuring SdkEventLoopGroup
* @return new Builder instance
*/
public static Builder builder();
/**
* Creates SdkEventLoopGroup with custom EventLoopGroup and auto-resolved ChannelFactory
* @param eventLoopGroup custom EventLoopGroup instance (caller manages lifecycle)
* @return configured SdkEventLoopGroup
*/
public static SdkEventLoopGroup create(EventLoopGroup eventLoopGroup);
/**
* Creates SdkEventLoopGroup with custom EventLoopGroup and ChannelFactory
* @param eventLoopGroup custom EventLoopGroup instance (caller manages lifecycle)
* @param channelFactory custom ChannelFactory for socket channels
* @return configured SdkEventLoopGroup
*/
public static SdkEventLoopGroup create(EventLoopGroup eventLoopGroup,
ChannelFactory<? extends Channel> channelFactory);
}Usage Examples:
import software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
// SDK-managed lifecycle (recommended)
SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()
.numberOfThreads(8)
.build();
NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(eventLoopGroup.toBuilder())
.build();
// Caller-managed lifecycle
NioEventLoopGroup customEventLoop = new NioEventLoopGroup(4);
SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.create(customEventLoop);
NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()
.eventLoopGroup(eventLoopGroup)
.build();
// Must manually close when using caller-managed
client.close();
customEventLoop.shutdownGracefully();Builder interface for configuring SdkEventLoopGroup instances with custom thread counts, factories, and channel types.
/**
* Builder for configuring SdkEventLoopGroup instances
*/
public interface Builder {
/**
* Sets the number of threads for the EventLoopGroup
* @param numberOfThreads thread count (default: available processors * 2)
* @return this builder for method chaining
*/
Builder numberOfThreads(Integer numberOfThreads);
/**
* Sets custom ThreadFactory for EventLoopGroup threads
* @param threadFactory custom thread factory for naming and configuration
* @return this builder for method chaining
*/
Builder threadFactory(ThreadFactory threadFactory);
/**
* Sets custom ChannelFactory for socket channels
* @param channelFactory factory for creating socket channels
* @return this builder for method chaining
*/
Builder channelFactory(ChannelFactory<? extends Channel> channelFactory);
/**
* Sets custom ChannelFactory for datagram channels
* @param datagramChannelFactory factory for creating datagram channels
* @return this builder for method chaining
*/
Builder datagramChannelFactory(ChannelFactory<? extends DatagramChannel> datagramChannelFactory);
/**
* Builds the configured SdkEventLoopGroup instance
* @return configured SdkEventLoopGroup
*/
SdkEventLoopGroup build();
}Configuration Examples:
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
// Custom thread configuration
ThreadFactory threadFactory = new ThreadFactory() {
private AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "aws-http-client-" + counter.incrementAndGet());
thread.setDaemon(true);
return thread;
}
};
SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()
.numberOfThreads(4)
.threadFactory(threadFactory)
.build();
// Custom channel factories
SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()
.channelFactory(NioSocketChannel::new)
.datagramChannelFactory(NioDatagramChannel::new)
.build();
// Sharing event loop across multiple clients
SdkEventLoopGroup sharedEventLoop = SdkEventLoopGroup.builder()
.numberOfThreads(8)
.build();
NettyNioAsyncHttpClient client1 = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(sharedEventLoop.toBuilder())
.build();
NettyNioAsyncHttpClient client2 = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(sharedEventLoop.toBuilder())
.build();When using eventLoopGroupBuilder() on the NettyNioAsyncHttpClient builder, the SDK manages the EventLoopGroup lifecycle:
// SDK creates and manages the EventLoopGroup
NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(SdkEventLoopGroup.builder().numberOfThreads(4))
.build();
// SDK automatically shuts down EventLoopGroup when client closes
client.close();When using eventLoopGroup() with a pre-created SdkEventLoopGroup, the caller is responsible for lifecycle management:
// Create and manage EventLoopGroup lifecycle
SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()
.numberOfThreads(4)
.build();
NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()
.eventLoopGroup(eventLoopGroup)
.build();
// Caller must close both client and event loop
client.close();
// eventLoopGroup shutdown is managed separatelyEvent loops can be shared across multiple HTTP clients for resource efficiency:
// Create shared event loop
SdkEventLoopGroup.Builder eventLoopBuilder = SdkEventLoopGroup.builder()
.numberOfThreads(8);
// Share across multiple clients (each gets its own instance but shares threads)
NettyNioAsyncHttpClient s3Client = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(eventLoopBuilder)
.build();
NettyNioAsyncHttpClient dynamoClient = NettyNioAsyncHttpClient.builder()
.eventLoopGroupBuilder(eventLoopBuilder)
.build();// Core Netty event loop interfaces
interface EventLoopGroup extends ScheduledExecutorService, Iterable<EventExecutor> {
EventLoop next();
ChannelFuture register(Channel channel);
Future<?> shutdownGracefully();
}
interface EventLoop extends OrderedEventExecutor, EventLoopGroup {
EventLoopGroup parent();
boolean inEventLoop();
boolean inEventLoop(Thread thread);
}
// Channel factory interfaces
interface ChannelFactory<T extends Channel> {
T newChannel();
}
interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {
ChannelId id();
EventLoop eventLoop();
ChannelPipeline pipeline();
boolean isOpen();
boolean isActive();
}
interface DatagramChannel extends Channel {
// UDP-specific channel operations
}// NIO-based implementations (most common)
class NioEventLoopGroup implements EventLoopGroup {
// Multi-threaded NIO event loop group
}
class NioSocketChannel implements SocketChannel {
// NIO TCP socket channel
}
class NioDatagramChannel implements DatagramChannel {
// NIO UDP datagram channel
}
// Epoll-based implementations (Linux only, higher performance)
class EpollEventLoopGroup implements EventLoopGroup {
// Linux epoll-based event loop group
}
class EpollSocketChannel implements SocketChannel {
// Linux epoll TCP socket channel
}interface ThreadFactory {
Thread newThread(Runnable r);
}
// Example custom implementation
class NamedThreadFactory implements ThreadFactory {
private final String namePrefix;
private final AtomicInteger threadNumber;
private final boolean daemon;
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, namePrefix + threadNumber.getAndIncrement());
thread.setDaemon(daemon);
return thread;
}
}Install with Tessl CLI
npx tessl i tessl/maven-software-amazon-awssdk--netty-nio-client