or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

event-loop.mdhttp-client.mdhttp2-config.mdindex.mdproxy-config.md

event-loop.mddocs/

0

# Event Loop Management

1

2

Event loop and channel factory management for efficient resource sharing and lifecycle control across multiple HTTP clients using Netty's EventLoopGroup infrastructure.

3

4

## Capabilities

5

6

### SdkEventLoopGroup

7

8

Wrapper for Netty EventLoopGroup that provides EventLoopGroup and ChannelFactory instances for the NettyNioAsyncHttpClient. Supports both managed (SDK-controlled) and unmanaged (caller-controlled) lifecycle patterns.

9

10

```java { .api }

11

/**

12

* SdkEventLoopGroup provides EventLoopGroup and ChannelFactory management for NettyNioAsyncHttpClient.

13

* Supports both managed lifecycle (created by SDK) and unmanaged lifecycle (provided by caller).

14

*/

15

public final class SdkEventLoopGroup {

16

/**

17

* Returns the underlying Netty EventLoopGroup

18

* @return the EventLoopGroup instance for handling I/O operations

19

*/

20

public EventLoopGroup eventLoopGroup();

21

22

/**

23

* Returns the socket channel factory for creating connections

24

* @return ChannelFactory for socket channels

25

*/

26

public ChannelFactory<? extends Channel> channelFactory();

27

28

/**

29

* Returns the datagram channel factory for UDP operations

30

* @return ChannelFactory for datagram channels

31

*/

32

public ChannelFactory<? extends DatagramChannel> datagramChannelFactory();

33

34

/**

35

* Creates a new builder for configuring SdkEventLoopGroup

36

* @return new Builder instance

37

*/

38

public static Builder builder();

39

40

/**

41

* Creates SdkEventLoopGroup with custom EventLoopGroup and auto-resolved ChannelFactory

42

* @param eventLoopGroup custom EventLoopGroup instance (caller manages lifecycle)

43

* @return configured SdkEventLoopGroup

44

*/

45

public static SdkEventLoopGroup create(EventLoopGroup eventLoopGroup);

46

47

/**

48

* Creates SdkEventLoopGroup with custom EventLoopGroup and ChannelFactory

49

* @param eventLoopGroup custom EventLoopGroup instance (caller manages lifecycle)

50

* @param channelFactory custom ChannelFactory for socket channels

51

* @return configured SdkEventLoopGroup

52

*/

53

public static SdkEventLoopGroup create(EventLoopGroup eventLoopGroup,

54

ChannelFactory<? extends Channel> channelFactory);

55

}

56

```

57

58

**Usage Examples:**

59

60

```java

61

import software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup;

62

import io.netty.channel.nio.NioEventLoopGroup;

63

import io.netty.channel.socket.nio.NioSocketChannel;

64

65

// SDK-managed lifecycle (recommended)

66

SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()

67

.numberOfThreads(8)

68

.build();

69

70

NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()

71

.eventLoopGroupBuilder(eventLoopGroup.toBuilder())

72

.build();

73

74

// Caller-managed lifecycle

75

NioEventLoopGroup customEventLoop = new NioEventLoopGroup(4);

76

SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.create(customEventLoop);

77

78

NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()

79

.eventLoopGroup(eventLoopGroup)

80

.build();

81

82

// Must manually close when using caller-managed

83

client.close();

84

customEventLoop.shutdownGracefully();

85

```

86

87

### SdkEventLoopGroup Builder

88

89

Builder interface for configuring SdkEventLoopGroup instances with custom thread counts, factories, and channel types.

90

91

```java { .api }

92

/**

93

* Builder for configuring SdkEventLoopGroup instances

94

*/

95

public interface Builder {

96

/**

97

* Sets the number of threads for the EventLoopGroup

98

* @param numberOfThreads thread count (default: available processors * 2)

99

* @return this builder for method chaining

100

*/

101

Builder numberOfThreads(Integer numberOfThreads);

102

103

/**

104

* Sets custom ThreadFactory for EventLoopGroup threads

105

* @param threadFactory custom thread factory for naming and configuration

106

* @return this builder for method chaining

107

*/

108

Builder threadFactory(ThreadFactory threadFactory);

109

110

/**

111

* Sets custom ChannelFactory for socket channels

112

* @param channelFactory factory for creating socket channels

113

* @return this builder for method chaining

114

*/

115

Builder channelFactory(ChannelFactory<? extends Channel> channelFactory);

116

117

/**

118

* Sets custom ChannelFactory for datagram channels

119

* @param datagramChannelFactory factory for creating datagram channels

120

* @return this builder for method chaining

121

*/

122

Builder datagramChannelFactory(ChannelFactory<? extends DatagramChannel> datagramChannelFactory);

123

124

/**

125

* Builds the configured SdkEventLoopGroup instance

126

* @return configured SdkEventLoopGroup

127

*/

128

SdkEventLoopGroup build();

129

}

130

```

131

132

**Configuration Examples:**

133

134

```java

135

import java.util.concurrent.ThreadFactory;

136

import java.util.concurrent.atomic.AtomicInteger;

137

138

// Custom thread configuration

139

ThreadFactory threadFactory = new ThreadFactory() {

140

private AtomicInteger counter = new AtomicInteger(0);

141

142

@Override

143

public Thread newThread(Runnable r) {

144

Thread thread = new Thread(r, "aws-http-client-" + counter.incrementAndGet());

145

thread.setDaemon(true);

146

return thread;

147

}

148

};

149

150

SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()

151

.numberOfThreads(4)

152

.threadFactory(threadFactory)

153

.build();

154

155

// Custom channel factories

156

SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()

157

.channelFactory(NioSocketChannel::new)

158

.datagramChannelFactory(NioDatagramChannel::new)

159

.build();

160

161

// Sharing event loop across multiple clients

162

SdkEventLoopGroup sharedEventLoop = SdkEventLoopGroup.builder()

163

.numberOfThreads(8)

164

.build();

165

166

NettyNioAsyncHttpClient client1 = NettyNioAsyncHttpClient.builder()

167

.eventLoopGroupBuilder(sharedEventLoop.toBuilder())

168

.build();

169

170

NettyNioAsyncHttpClient client2 = NettyNioAsyncHttpClient.builder()

171

.eventLoopGroupBuilder(sharedEventLoop.toBuilder())

172

.build();

173

```

174

175

## Event Loop Lifecycle Management

176

177

### SDK-Managed Lifecycle

178

179

When using `eventLoopGroupBuilder()` on the NettyNioAsyncHttpClient builder, the SDK manages the EventLoopGroup lifecycle:

180

181

```java

182

// SDK creates and manages the EventLoopGroup

183

NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()

184

.eventLoopGroupBuilder(SdkEventLoopGroup.builder().numberOfThreads(4))

185

.build();

186

187

// SDK automatically shuts down EventLoopGroup when client closes

188

client.close();

189

```

190

191

### Caller-Managed Lifecycle

192

193

When using `eventLoopGroup()` with a pre-created SdkEventLoopGroup, the caller is responsible for lifecycle management:

194

195

```java

196

// Create and manage EventLoopGroup lifecycle

197

SdkEventLoopGroup eventLoopGroup = SdkEventLoopGroup.builder()

198

.numberOfThreads(4)

199

.build();

200

201

NettyNioAsyncHttpClient client = NettyNioAsyncHttpClient.builder()

202

.eventLoopGroup(eventLoopGroup)

203

.build();

204

205

// Caller must close both client and event loop

206

client.close();

207

// eventLoopGroup shutdown is managed separately

208

```

209

210

### Sharing Event Loops

211

212

Event loops can be shared across multiple HTTP clients for resource efficiency:

213

214

```java

215

// Create shared event loop

216

SdkEventLoopGroup.Builder eventLoopBuilder = SdkEventLoopGroup.builder()

217

.numberOfThreads(8);

218

219

// Share across multiple clients (each gets its own instance but shares threads)

220

NettyNioAsyncHttpClient s3Client = NettyNioAsyncHttpClient.builder()

221

.eventLoopGroupBuilder(eventLoopBuilder)

222

.build();

223

224

NettyNioAsyncHttpClient dynamoClient = NettyNioAsyncHttpClient.builder()

225

.eventLoopGroupBuilder(eventLoopBuilder)

226

.build();

227

```

228

229

## Types

230

231

### Netty Event Loop Types

232

233

```java { .api }

234

// Core Netty event loop interfaces

235

interface EventLoopGroup extends ScheduledExecutorService, Iterable<EventExecutor> {

236

EventLoop next();

237

ChannelFuture register(Channel channel);

238

Future<?> shutdownGracefully();

239

}

240

241

interface EventLoop extends OrderedEventExecutor, EventLoopGroup {

242

EventLoopGroup parent();

243

boolean inEventLoop();

244

boolean inEventLoop(Thread thread);

245

}

246

247

// Channel factory interfaces

248

interface ChannelFactory<T extends Channel> {

249

T newChannel();

250

}

251

252

interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {

253

ChannelId id();

254

EventLoop eventLoop();

255

ChannelPipeline pipeline();

256

boolean isOpen();

257

boolean isActive();

258

}

259

260

interface DatagramChannel extends Channel {

261

// UDP-specific channel operations

262

}

263

```

264

265

### Common Netty Implementations

266

267

```java { .api }

268

// NIO-based implementations (most common)

269

class NioEventLoopGroup implements EventLoopGroup {

270

// Multi-threaded NIO event loop group

271

}

272

273

class NioSocketChannel implements SocketChannel {

274

// NIO TCP socket channel

275

}

276

277

class NioDatagramChannel implements DatagramChannel {

278

// NIO UDP datagram channel

279

}

280

281

// Epoll-based implementations (Linux only, higher performance)

282

class EpollEventLoopGroup implements EventLoopGroup {

283

// Linux epoll-based event loop group

284

}

285

286

class EpollSocketChannel implements SocketChannel {

287

// Linux epoll TCP socket channel

288

}

289

```

290

291

### Thread Factory

292

293

```java { .api }

294

interface ThreadFactory {

295

Thread newThread(Runnable r);

296

}

297

298

// Example custom implementation

299

class NamedThreadFactory implements ThreadFactory {

300

private final String namePrefix;

301

private final AtomicInteger threadNumber;

302

private final boolean daemon;

303

304

public Thread newThread(Runnable r) {

305

Thread thread = new Thread(r, namePrefix + threadNumber.getAndIncrement());

306

thread.setDaemon(daemon);

307

return thread;

308

}

309

}

310

```