or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cluster-token-client.mdcodec-system.mdcommand-interface.mdconfiguration.mdindex.mdnetwork-transport.md

codec-system.mddocs/

0

# Codec System

1

2

The codec system provides request and response encoding/decoding for efficient network serialization with extensible registries for custom data types and protocols.

3

4

## Capabilities

5

6

### Request Data Writer Registry

7

8

Registry system for managing request data encoders that serialize different types of cluster requests into ByteBuf format for network transmission.

9

10

```java { .api }

11

/**

12

* Registry for request data writers that encode requests for network transmission

13

*/

14

public final class RequestDataWriterRegistry {

15

/**

16

* Register a writer for a specific request type

17

* @param type request type constant (e.g., TYPE_PING, TYPE_FLOW)

18

* @param writer entity writer implementation for this type

19

* @return true if writer was registered, false if type already has a writer

20

*/

21

public static <T> boolean addWriter(int type, EntityWriter<T, ByteBuf> writer);

22

23

/**

24

* Get writer for a specific request type

25

* @param type request type constant

26

* @return writer for the type, or null if no writer registered

27

*/

28

public static EntityWriter<Object, ByteBuf> getWriter(int type);

29

30

/**

31

* Remove writer for a specific request type

32

* @param type request type constant to remove

33

* @return true if writer was removed, false if no writer existed

34

*/

35

public static boolean remove(int type);

36

}

37

```

38

39

**Usage Examples:**

40

41

```java

42

import com.alibaba.csp.sentinel.cluster.client.codec.registry.RequestDataWriterRegistry;

43

import com.alibaba.csp.sentinel.cluster.client.ClientConstants;

44

import com.alibaba.csp.sentinel.cluster.codec.EntityWriter;

45

import io.netty.buffer.ByteBuf;

46

47

// Register a custom writer for a new request type

48

EntityWriter<CustomRequestData, ByteBuf> customWriter = new CustomRequestDataWriter();

49

boolean registered = RequestDataWriterRegistry.addWriter(100, customWriter);

50

51

if (registered) {

52

System.out.println("Custom writer registered");

53

} else {

54

System.out.println("Writer for type 100 already exists");

55

}

56

57

// Get writer for existing type

58

EntityWriter<Object, ByteBuf> flowWriter = RequestDataWriterRegistry.getWriter(ClientConstants.TYPE_FLOW);

59

if (flowWriter != null) {

60

// Use writer to encode flow request data

61

}

62

63

// Remove custom writer

64

RequestDataWriterRegistry.remove(100);

65

```

66

67

### Response Data Decoder Registry

68

69

Registry system for managing response data decoders that deserialize network responses from ByteBuf format into Java objects.

70

71

```java { .api }

72

/**

73

* Registry for response data decoders that decode responses from network transmission

74

*/

75

public final class ResponseDataDecodeRegistry {

76

/**

77

* Register a decoder for a specific response type

78

* @param type response type constant (e.g., TYPE_PING, TYPE_FLOW)

79

* @param decoder entity decoder implementation for this type

80

* @return true if decoder was registered, false if type already has a decoder

81

*/

82

public static boolean addDecoder(int type, EntityDecoder<ByteBuf, ?> decoder);

83

84

/**

85

* Get decoder for a specific response type

86

* @param type response type constant

87

* @return decoder for the type, or null if no decoder registered

88

*/

89

public static EntityDecoder<ByteBuf, Object> getDecoder(int type);

90

91

/**

92

* Remove decoder for a specific response type

93

* @param type response type constant to remove

94

* @return true if decoder was removed, false if no decoder existed

95

*/

96

public static boolean removeDecoder(int type);

97

}

98

```

99

100

**Usage Examples:**

101

102

```java

103

import com.alibaba.csp.sentinel.cluster.client.codec.registry.ResponseDataDecodeRegistry;

104

import com.alibaba.csp.sentinel.cluster.codec.EntityDecoder;

105

import io.netty.buffer.ByteBuf;

106

107

// Register custom decoder

108

EntityDecoder<ByteBuf, CustomResponseData> customDecoder = new CustomResponseDataDecoder();

109

boolean registered = ResponseDataDecodeRegistry.addDecoder(200, customDecoder);

110

111

// Get decoder for ping responses

112

EntityDecoder<ByteBuf, Object> pingDecoder = ResponseDataDecodeRegistry.getDecoder(ClientConstants.TYPE_PING);

113

if (pingDecoder != null) {

114

// Use decoder to parse ping response

115

}

116

117

// Remove custom decoder

118

ResponseDataDecodeRegistry.removeDecoder(200);

119

```

120

121

### Built-in Request Writers

122

123

The system includes several built-in writers for standard request types that are automatically registered during initialization.

124

125

**Flow Request Writer:**

126

- **Type**: `ClientConstants.TYPE_FLOW`

127

- **Data**: `FlowRequestData` containing flow rule ID, token count, and priority

128

- **Usage**: Regular flow control token requests

129

130

**Parameterized Flow Request Writer:**

131

- **Type**: `ClientConstants.TYPE_PARAM_FLOW`

132

- **Data**: `ParamFlowRequestData` containing flow rule ID, token count, and parameters

133

- **Usage**: Parameter-specific flow control token requests

134

- **Configuration**: Supports max parameter byte size limits

135

136

**Ping Request Writer:**

137

- **Type**: `ClientConstants.TYPE_PING`

138

- **Data**: Ping data for server connectivity checks

139

- **Usage**: Health checks and connectivity monitoring

140

141

**Writer Usage Examples:**

142

143

```java

144

import com.alibaba.csp.sentinel.cluster.request.data.FlowRequestData;

145

import com.alibaba.csp.sentinel.cluster.request.data.ParamFlowRequestData;

146

import java.util.Arrays;

147

148

// Flow request data

149

FlowRequestData flowData = new FlowRequestData()

150

.setFlowId(12345L)

151

.setCount(1)

152

.setPriority(false);

153

154

// Parameterized flow request data

155

ParamFlowRequestData paramData = new ParamFlowRequestData()

156

.setFlowId(67890L)

157

.setCount(2)

158

.setParams(Arrays.asList("user123", "premium"));

159

160

// These data objects are automatically encoded by registered writers

161

```

162

163

### Built-in Response Decoders

164

165

The system includes built-in decoders for standard response types.

166

167

**Flow Response Decoder:**

168

- **Types**: `ClientConstants.TYPE_FLOW`, `ClientConstants.TYPE_PARAM_FLOW`

169

- **Data**: `FlowTokenResponseData` containing remaining count and wait time

170

- **Usage**: Decoding flow control token responses

171

172

**Ping Response Decoder:**

173

- **Type**: `ClientConstants.TYPE_PING`

174

- **Data**: Ping response data for connectivity confirmation

175

- **Usage**: Health check response processing

176

177

### Netty Pipeline Codecs

178

179

The codec system integrates with Netty pipeline handlers for seamless request/response processing.

180

181

```java { .api }

182

/**

183

* Netty encoder for outgoing cluster requests

184

*/

185

public class NettyRequestEncoder extends MessageToByteEncoder<ClusterRequest> {

186

// Automatically encodes ClusterRequest objects using registered writers

187

}

188

189

/**

190

* Netty decoder for incoming cluster responses

191

*/

192

public class NettyResponseDecoder extends ByteToMessageDecoder {

193

// Automatically decodes network data into ClusterResponse objects using registered decoders

194

}

195

```

196

197

**Pipeline Integration:**

198

199

```java

200

// The codec system is automatically integrated into the Netty pipeline:

201

// 1. LengthFieldBasedFrameDecoder - handles message framing

202

// 2. NettyResponseDecoder - decodes responses using registry

203

// 3. LengthFieldPrepender - adds length headers

204

// 4. NettyRequestEncoder - encodes requests using registry

205

// 5. TokenClientHandler - handles request/response correlation

206

```

207

208

### Entity Provider System

209

210

The codec system uses an entity provider pattern for accessing writers and decoders through SPI loading.

211

212

```java { .api }

213

/**

214

* Provider for entity codecs using SPI loading mechanism

215

*/

216

public final class ClientEntityCodecProvider {

217

/**

218

* Get the configured request entity writer

219

* @return request entity writer instance, or null if not configured

220

*/

221

public static RequestEntityWriter getRequestEntityWriter();

222

223

/**

224

* Get the configured response entity decoder

225

* @return response entity decoder instance, or null if not configured

226

*/

227

public static ResponseEntityDecoder getResponseEntityDecoder();

228

}

229

```

230

231

**Usage Examples:**

232

233

```java

234

import com.alibaba.csp.sentinel.cluster.client.codec.ClientEntityCodecProvider;

235

import com.alibaba.csp.sentinel.cluster.codec.request.RequestEntityWriter;

236

import com.alibaba.csp.sentinel.cluster.codec.response.ResponseEntityDecoder;

237

238

// Get configured codecs

239

RequestEntityWriter writer = ClientEntityCodecProvider.getRequestEntityWriter();

240

ResponseEntityDecoder decoder = ClientEntityCodecProvider.getResponseEntityDecoder();

241

242

if (writer != null) {

243

System.out.println("Request writer available: " + writer.getClass().getName());

244

} else {

245

System.out.println("No request writer configured via SPI");

246

}

247

```

248

249

### Custom Codec Implementation

250

251

You can implement custom codecs for new request/response types.

252

253

**Custom Request Writer:**

254

255

```java

256

import com.alibaba.csp.sentinel.cluster.codec.EntityWriter;

257

import io.netty.buffer.ByteBuf;

258

259

public class CustomRequestDataWriter implements EntityWriter<CustomRequestData, ByteBuf> {

260

@Override

261

public void writeTo(ByteBuf target, CustomRequestData source) throws Exception {

262

// Write custom data fields to ByteBuf

263

target.writeInt(source.getId());

264

target.writeLong(source.getTimestamp());

265

266

byte[] nameBytes = source.getName().getBytes("UTF-8");

267

target.writeInt(nameBytes.length);

268

target.writeBytes(nameBytes);

269

}

270

}

271

272

// Register the custom writer

273

RequestDataWriterRegistry.addWriter(CUSTOM_TYPE, new CustomRequestDataWriter());

274

```

275

276

**Custom Response Decoder:**

277

278

```java

279

import com.alibaba.csp.sentinel.cluster.codec.EntityDecoder;

280

import io.netty.buffer.ByteBuf;

281

282

public class CustomResponseDataDecoder implements EntityDecoder<ByteBuf, CustomResponseData> {

283

@Override

284

public CustomResponseData decode(ByteBuf source) throws Exception {

285

// Read custom data fields from ByteBuf

286

int id = source.readInt();

287

long timestamp = source.readLong();

288

289

int nameLength = source.readInt();

290

byte[] nameBytes = new byte[nameLength];

291

source.readBytes(nameBytes);

292

String name = new String(nameBytes, "UTF-8");

293

294

return new CustomResponseData(id, timestamp, name);

295

}

296

}

297

298

// Register the custom decoder

299

ResponseDataDecodeRegistry.addDecoder(CUSTOM_TYPE, new CustomResponseDataDecoder());

300

```

301

302

### Initialization and Setup

303

304

The codec system is automatically initialized through the `DefaultClusterClientInitFunc` class during Sentinel startup.

305

306

```java { .api }

307

/**

308

* Initialization function for default cluster client components

309

* Automatically registers default codecs for built-in request/response types

310

*/

311

@InitOrder(0)

312

public class DefaultClusterClientInitFunc implements InitFunc {

313

/**

314

* Initialize default entity writers and decoders

315

* @throws Exception if initialization fails

316

*/

317

public void init() throws Exception;

318

}

319

```

320

321

**Automatic Registration Process:**

322

323

```java

324

// The initialization process automatically registers:

325

326

// Request writers

327

RequestDataWriterRegistry.addWriter(ClientConstants.TYPE_PING, new PingRequestDataWriter());

328

RequestDataWriterRegistry.addWriter(ClientConstants.TYPE_FLOW, new FlowRequestDataWriter());

329

330

// Parameterized flow writer with optional size limit

331

Integer maxParamByteSize = ClusterClientStartUpConfig.getMaxParamByteSize();

332

if (maxParamByteSize == null) {

333

RequestDataWriterRegistry.addWriter(ClientConstants.TYPE_PARAM_FLOW, new ParamFlowRequestDataWriter());

334

} else {

335

RequestDataWriterRegistry.addWriter(ClientConstants.TYPE_PARAM_FLOW, new ParamFlowRequestDataWriter(maxParamByteSize));

336

}

337

338

// Response decoders

339

ResponseDataDecodeRegistry.addDecoder(ClientConstants.TYPE_PING, new PingResponseDataDecoder());

340

ResponseDataDecodeRegistry.addDecoder(ClientConstants.TYPE_FLOW, new FlowResponseDataDecoder());

341

ResponseDataDecodeRegistry.addDecoder(ClientConstants.TYPE_PARAM_FLOW, new FlowResponseDataDecoder());

342

```

343

344

### Configuration Parameters

345

346

The codec system supports configuration parameters for customization.

347

348

**Parameter Serialization Limits:**

349

350

```java

351

import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientStartUpConfig;

352

353

// Configure maximum parameter byte size

354

Integer maxParamBytes = ClusterClientStartUpConfig.getMaxParamByteSize();

355

if (maxParamBytes != null) {

356

// Use custom limit for parameter serialization

357

ParamFlowRequestDataWriter writer = new ParamFlowRequestDataWriter(maxParamBytes);

358

RequestDataWriterRegistry.addWriter(ClientConstants.TYPE_PARAM_FLOW, writer);

359

}

360

361

// System property: -Dcsp.sentinel.cluster.max.param.byte.size=2048

362

```

363

364

### Thread Safety

365

366

All registry operations are thread-safe and can be called from multiple threads simultaneously. However, it's recommended to register custom codecs during application initialization before starting the cluster client.

367

368

### Performance Considerations

369

370

**Codec Efficiency:**

371

- Use efficient serialization formats for custom codecs

372

- Avoid unnecessary object allocation during encoding/decoding

373

- Consider using object pooling for frequently used data structures

374

375

**Registry Lookup:**

376

- Registry lookups are O(1) HashMap operations

377

- Cache codec instances when possible

378

- Register codecs once during initialization rather than repeatedly