@interopio/bridge 0.0.1-alpha → 0.0.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/bin/bridge.js +1 -1
  2. package/changelog.md +24 -0
  3. package/dist/main.js +2201 -0
  4. package/dist/main.js.map +7 -0
  5. package/package.json +9 -6
  6. package/gen/instance/GeneratedBuildInfo.ts +0 -4
  7. package/src/cluster/Address.ts +0 -57
  8. package/src/cluster/Cluster.ts +0 -13
  9. package/src/cluster/Endpoint.ts +0 -5
  10. package/src/cluster/Member.ts +0 -9
  11. package/src/cluster/MembershipListener.ts +0 -6
  12. package/src/config/Config.ts +0 -100
  13. package/src/config/DiscoveryConfig.ts +0 -21
  14. package/src/config/Duration.ts +0 -168
  15. package/src/config/KubernetesConfig.ts +0 -7
  16. package/src/config/NamedDiscoveryConfig.ts +0 -17
  17. package/src/config/Properties.ts +0 -49
  18. package/src/config/index.ts +0 -1
  19. package/src/discovery/SimpleDiscoveryNode.ts +0 -14
  20. package/src/discovery/index.ts +0 -207
  21. package/src/discovery/multicast/MulticastDiscoveryStrategy.ts +0 -141
  22. package/src/discovery/multicast/MulticastDiscoveryStrategyFactory.ts +0 -30
  23. package/src/discovery/multicast/MulticastProperties.ts +0 -4
  24. package/src/discovery/settings.ts +0 -37
  25. package/src/error/RequestFailure.ts +0 -48
  26. package/src/gossip/ApplicationState.ts +0 -48
  27. package/src/gossip/EndpointState.ts +0 -141
  28. package/src/gossip/FailureDetector.ts +0 -235
  29. package/src/gossip/Gossiper.ts +0 -1133
  30. package/src/gossip/HeartbeatState.ts +0 -66
  31. package/src/gossip/Messenger.ts +0 -130
  32. package/src/gossip/VersionedValue.ts +0 -59
  33. package/src/index.ts +0 -3
  34. package/src/instance/AddressPicker.ts +0 -245
  35. package/src/instance/BridgeNode.ts +0 -141
  36. package/src/instance/ClusterTopologyIntentTracker.ts +0 -4
  37. package/src/io/VersionedSerializer.ts +0 -230
  38. package/src/io/util.ts +0 -117
  39. package/src/kubernetes/DnsEndpointResolver.ts +0 -70
  40. package/src/kubernetes/KubernetesApiEndpointResolver.ts +0 -111
  41. package/src/kubernetes/KubernetesApiProvider.ts +0 -75
  42. package/src/kubernetes/KubernetesClient.ts +0 -264
  43. package/src/kubernetes/KubernetesConfig.ts +0 -130
  44. package/src/kubernetes/KubernetesDiscoveryStrategy.ts +0 -30
  45. package/src/kubernetes/KubernetesDiscoveryStrategyFactory.ts +0 -71
  46. package/src/kubernetes/KubernetesEndpointResolver.ts +0 -43
  47. package/src/kubernetes/KubernetesProperties.ts +0 -22
  48. package/src/license/BridgeLicenseValidator.ts +0 -19
  49. package/src/license/LicenseValidator.ts +0 -114
  50. package/src/license/types.ts +0 -40
  51. package/src/logging.ts +0 -22
  52. package/src/main.mts +0 -53
  53. package/src/net/Action.ts +0 -143
  54. package/src/net/AddressSerializer.ts +0 -44
  55. package/src/net/ByteBufferAllocator.ts +0 -27
  56. package/src/net/FrameDecoder.ts +0 -314
  57. package/src/net/FrameEncoder.ts +0 -138
  58. package/src/net/HandshakeProtocol.ts +0 -143
  59. package/src/net/InboundConnection.ts +0 -108
  60. package/src/net/InboundConnectionInitiator.ts +0 -150
  61. package/src/net/InboundMessageHandler.ts +0 -377
  62. package/src/net/InboundSink.ts +0 -38
  63. package/src/net/Message.ts +0 -428
  64. package/src/net/OutboundConnection.ts +0 -1141
  65. package/src/net/OutboundConnectionInitiator.ts +0 -76
  66. package/src/net/RequestCallbacks.ts +0 -148
  67. package/src/net/ResponseHandler.ts +0 -30
  68. package/src/net/ShareableBytes.ts +0 -125
  69. package/src/net/internal/AsyncResourceExecutor.ts +0 -464
  70. package/src/net/internal/AsyncSocketPromise.ts +0 -37
  71. package/src/net/internal/channel/ChannelHandlerAdapter.ts +0 -99
  72. package/src/net/internal/channel/types.ts +0 -188
  73. package/src/utils/bigint.ts +0 -23
  74. package/src/utils/buffer.ts +0 -434
  75. package/src/utils/clock.ts +0 -148
  76. package/src/utils/collections.ts +0 -283
  77. package/src/utils/crc.ts +0 -39
  78. package/src/utils/internal/IpAddressUtil.ts +0 -161
  79. package/src/utils/memory/BufferPools.ts +0 -40
  80. package/src/utils/network.ts +0 -130
  81. package/src/utils/promise.ts +0 -38
  82. package/src/utils/uuid.ts +0 -5
  83. package/src/utils/vint.ts +0 -238
  84. package/src/version/MemberVersion.ts +0 -42
  85. package/src/version/Version.ts +0 -12
@@ -1,314 +0,0 @@
1
- import {shareableBytes, type ShareableBytes} from './ShareableBytes.ts';
2
- import type {ByteBufferAllocator} from './ByteBufferAllocator.ts';
3
- import {type ByteBuffer} from '../utils/buffer.ts';
4
- import {computeCrc32, crc24} from '../utils/crc.ts';
5
-
6
- export type ValidFrame = { corrupted: false, size: number, selfContained: boolean, contents: ShareableBytes };
7
- export type CorruptedFrame
8
- = { corrupted: true, recoverable: true, size: number, selfContained: boolean, readCrc: number, computedCrc: number }
9
- | { corrupted: true, recoverable: false, readCrc: number, computedCrc: number };
10
- export type Frame = ValidFrame | CorruptedFrame;
11
- export type FrameProcessor = (frame: Frame) => boolean;
12
- const HEADER_LENGTH = 6;
13
- const TRAILER_LENGTH = 4;
14
- const HEADER_AND_TRAILER_LENGTH = HEADER_LENGTH + TRAILER_LENGTH;
15
-
16
- const TMP = new DataView(new ArrayBuffer(8));
17
- export function reverseBytes32(i: number): number {
18
- TMP.setInt32(0, i);
19
- return TMP.getInt32(0, true);
20
- }
21
- function reverseBytes64(i: bigint): bigint {
22
- TMP.setBigInt64(0, i);
23
- return TMP.getBigInt64(0, true);
24
- }
25
-
26
- // fill target from source up to targetPosition
27
- function copyToSize(source: ByteBuffer, target: ByteBuffer, targetPosition: number): boolean {
28
- const length = targetPosition - target.position;
29
- if (length < 0) {
30
- return true;
31
- }
32
- const extra = source.remaining - length;
33
- if (extra <= 0) {
34
- target.setByteBuffer(source);
35
- return false;
36
- }
37
- source.limit = source.position + length;
38
- target.setByteBuffer(source);
39
- source.limit = source.position + extra;
40
- return true;
41
- }
42
-
43
- function readHeader6b(frame: ByteBuffer, begin: number): bigint {
44
- let header6b: bigint;
45
- if (frame.limit - begin >= 8) {
46
- header6b = frame.getBigInt64();
47
- if (frame.order === 'big-endian') {
48
- header6b = reverseBytes64(header6b);
49
- }
50
- header6b &= 0xffffffffffffn;
51
- } else {
52
- header6b = 0n;
53
- for (let i = 0; i < HEADER_LENGTH; i++) {
54
- header6b |= (BigInt(frame.getInt8(begin + i))) << BigInt(i * 8);
55
- }
56
- }
57
- return header6b;
58
- }
59
-
60
- function isSelfContained(header6b: bigint): boolean {
61
- return (header6b & BigInt(1 << 17)) !== 0n;
62
- }
63
-
64
- function payloadLength(header6b: bigint): number {
65
- return Number(header6b & 0x0ffffffffn) & 0x1FFFF;
66
- }
67
-
68
- function headerCrc(header6b: bigint): number {
69
- return Number(((header6b >> 24n) & 0x0ffffffffffn)) & 0xFFFFFF;
70
- }
71
-
72
- function verifyHeader6b(header6b: bigint): CorruptedFrame | undefined {
73
- const computeLengthCrc = crc24(header6b, 3);
74
- const readLengthCrc = headerCrc(header6b);
75
- return readLengthCrc === computeLengthCrc ? undefined : {corrupted: true, recoverable: false, readCrc: readLengthCrc, computedCrc: computeLengthCrc};
76
- }
77
-
78
-
79
- abstract class FrameDecoder {
80
- protected allocator: ByteBufferAllocator;
81
-
82
- private readonly frames: Frame[] = [];
83
- private active: boolean = false;
84
-
85
- constructor(allocator: ByteBufferAllocator) {
86
- this.allocator = allocator;
87
- }
88
- private processor: FrameProcessor = (frame) => {
89
- throw new Error('processor not set')
90
- };
91
-
92
- activate(processor: FrameProcessor): void {
93
- this.processor = processor;
94
- this.active = true;
95
- }
96
-
97
- reactivate(): void {
98
- if (this.active) {
99
- throw new Error('already active');
100
- }
101
-
102
- if (this.deliver(this.processor)) {
103
- this.active = true;
104
- }
105
- }
106
-
107
- discard(): void {
108
- this.active = false;
109
- this.processor = (frame) => {throw new Error('frame processor closed')};
110
- if (this._stash) {
111
- const bytes = this._stash;
112
- delete this._stash;
113
- this.allocator.put(bytes);
114
- }
115
- while (this.frames.length > 0) {
116
- const frame = this.frames.shift();
117
- FrameDecoder.releaseFrame(frame);
118
- }
119
- }
120
-
121
- private static isFrameConsumed(frame: Frame): boolean {
122
- if (frame.corrupted === false) {
123
- return !frame.contents.hasRemaining;
124
- }
125
- return true;
126
- }
127
-
128
- private static releaseFrame(frame: Frame): void {
129
- if (frame.corrupted === false) {
130
- frame.contents.release();
131
- }
132
- // else, corrupted frames are not released
133
- }
134
-
135
- private deliver(process: FrameProcessor): boolean {
136
-
137
- let deliver = true;
138
- while (deliver && this.frames.length > 0) {
139
- const frame = this.frames[0];
140
- deliver = process(frame);
141
- if (deliver && !FrameDecoder.isFrameConsumed(frame)) {
142
- throw new Error('frame not fully consumed');
143
- }
144
- if (deliver || FrameDecoder.isFrameConsumed(frame)) {
145
- this.frames.shift();
146
- FrameDecoder.releaseFrame(frame);
147
- }
148
- }
149
- return deliver;
150
- }
151
-
152
- private decode(frames: Frame[], bytes: ShareableBytes): void {
153
- this.doDecode(frames, bytes, HEADER_LENGTH);
154
- }
155
-
156
- private _stash: ByteBuffer;
157
-
158
- private stash(input: ShareableBytes, stashLength: number, begin: number, length: number): void {
159
- const out = this.allocator.getAtLeast(stashLength);
160
- const array = new Uint8Array(length);
161
- input.get().getUint8Array(array, begin, length);
162
- out.setUint8Array(array);
163
- out.position = length;
164
- this._stash = out;
165
- }
166
-
167
- protected abstract readHeader(frame: ByteBuffer, begin: number): bigint
168
-
169
- protected abstract verifyHeader(header: bigint): CorruptedFrame | undefined;
170
-
171
- protected abstract frameLength(header: bigint): number;
172
-
173
- protected abstract unpackFrame(frame: ShareableBytes, begin: number, end: number, header: bigint): Frame;
174
-
175
- protected doDecode(frames: Frame[], newBytes: ShareableBytes, headerLength: number): void {
176
- const input = newBytes.get();
177
- try {
178
- if (this._stash !== undefined) {
179
- if (!copyToSize(input, this._stash, headerLength)) {
180
- return;
181
- }
182
- const header = this.readHeader(this._stash, 0);
183
- const c = this.verifyHeader(header);
184
- if (c !== undefined) {
185
- this.discard();
186
- frames.push(c);
187
- return;
188
- }
189
- const frameLength = this.frameLength(header);
190
- this._stash = this.ensureCapacity(this._stash, frameLength);
191
-
192
- if (!copyToSize(input, this._stash, frameLength)) {
193
- return;
194
- }
195
-
196
- const stashed = shareableBytes(this._stash);
197
-
198
- this._stash.flip();
199
- delete this._stash;
200
-
201
- try {
202
- frames.push(this.unpackFrame(stashed, 0, frameLength, header));
203
- } finally {
204
- stashed.release();
205
- }
206
- }
207
-
208
- let begin = input.position;
209
- const limit = input.limit;
210
- while (begin < limit) {
211
- const remaining = limit - begin;
212
- if (remaining < headerLength) {
213
- this.stash(newBytes, headerLength, begin, remaining);
214
- return;
215
- }
216
-
217
- const header = this.readHeader(input, begin);
218
- const c = this.verifyHeader(header);
219
- if (c !== undefined) {
220
- frames.push(c);
221
- return;
222
- }
223
-
224
- const frameLength = this.frameLength(header);
225
- if (remaining < frameLength) {
226
- this.stash(newBytes, frameLength, begin, remaining);
227
- return;
228
- }
229
-
230
- frames.push(this.unpackFrame(newBytes, begin, begin + frameLength, header));
231
- begin += frameLength;
232
- }
233
- } finally {
234
- newBytes.release();
235
- }
236
- }
237
-
238
-
239
- receive(buffer: ByteBuffer) {
240
- this.decode(this.frames, shareableBytes(buffer));
241
- if (this.active) {
242
- this.active = this.deliver(this.processor);
243
- }
244
- }
245
-
246
- private ensureCapacity(buffer: ByteBuffer, capacity: number) {
247
- if (buffer.capacity >= capacity) {
248
- return buffer;
249
- }
250
- const newBuffer = this.allocator.getAtLeast(capacity);
251
- buffer.flip();
252
- newBuffer.setByteBuffer(buffer);
253
- this.allocator.put(buffer);
254
- return newBuffer;
255
- }
256
- }
257
-
258
- class FrameDecoderCrc extends FrameDecoder {
259
-
260
- protected readHeader(frame: ByteBuffer, begin: number): bigint {
261
- return readHeader6b(frame, begin);
262
- }
263
-
264
- protected verifyHeader(header: bigint): CorruptedFrame | undefined {
265
- return verifyHeader6b(header);
266
- }
267
-
268
- protected frameLength(header: bigint): number {
269
- return payloadLength(header) + HEADER_AND_TRAILER_LENGTH;
270
- }
271
-
272
- protected unpackFrame(bytes: ShareableBytes, begin: number, end: number, header6b: bigint): Frame {
273
- const input = bytes.get();
274
- const selfContained = isSelfContained(header6b);
275
- let readFullCrc = input.getInt32(end - TRAILER_LENGTH);
276
- if (input.order === 'big-endian') {
277
- readFullCrc = reverseBytes32(readFullCrc);
278
- }
279
- const computedCrc = computeCrc32(input, begin + HEADER_LENGTH, end - TRAILER_LENGTH);
280
-
281
- if (computedCrc !== readFullCrc) {
282
- return {corrupted: true, recoverable: true, size: end - begin, readCrc: readFullCrc, computedCrc, selfContained};
283
- }
284
-
285
- const contents = bytes.slice(begin + HEADER_LENGTH, end - TRAILER_LENGTH);
286
- return {corrupted: false, contents, size: contents.remaining, selfContained};
287
- }
288
- }
289
-
290
- class FrameDecoderUnprotected extends FrameDecoder {
291
- protected readHeader(frame: ByteBuffer, begin: number): bigint {
292
- return readHeader6b(frame, begin);
293
- }
294
- protected verifyHeader(header: bigint): CorruptedFrame | undefined {
295
- return verifyHeader6b(header);
296
- }
297
- protected frameLength(header: bigint): number {
298
- return payloadLength(header) + HEADER_LENGTH;
299
- }
300
-
301
- protected unpackFrame(bytes: ShareableBytes, begin: number, end: number, header6b: bigint): Frame {
302
- const selfContained = isSelfContained(header6b);
303
- const contents = bytes.slice(begin + HEADER_LENGTH, end);
304
- return {corrupted: false, contents, size: end - begin, selfContained};
305
- }
306
- }
307
-
308
- export type {FrameDecoder};
309
- export function createUnprotected(allocator: ByteBufferAllocator): FrameDecoder {
310
- return new FrameDecoderUnprotected(allocator);
311
- }
312
- export function createCrc(allocator: ByteBufferAllocator): FrameDecoder {
313
- return new FrameDecoderCrc(allocator);
314
- }
@@ -1,138 +0,0 @@
1
- import {allocate, type ByteBuffer} from '../utils/buffer.ts';
2
- import {computeCrc32, crc24} from '../utils/crc.ts';
3
- import {reverseBytes32} from './FrameDecoder.ts';
4
-
5
- import {ChannelHandlerAdapter} from './internal/channel/ChannelHandlerAdapter.ts';
6
-
7
- const HEADER_LENGTH = 6;
8
- const TRAILER_LENGTH = 4;
9
- const HEADER_AND_TRAILER_LENGTH = HEADER_LENGTH + TRAILER_LENGTH;
10
-
11
- function put3b(frame: ByteBuffer, index: number, value: number) {
12
- frame.setInt8(index, value);
13
- frame.setInt8(index + 1, value >>> 8);
14
- frame.setInt8(index + 2, value >>> 16);
15
- }
16
-
17
- function writeHeader(frame: ByteBuffer, selfContained: boolean, payloadLength: number) {
18
- let header3b: bigint = BigInt(payloadLength);
19
- if (selfContained) {
20
- header3b |= BigInt(1 << 17);
21
- }
22
- const crc = crc24(header3b, 3);
23
- put3b(frame, 0, Number(header3b));
24
- put3b(frame, 3, crc);
25
- }
26
-
27
- abstract class FrameEncoder extends ChannelHandlerAdapter {
28
- get allocator(): PayloadAllocator {
29
- return (capacity: number, selfContained = true) => new Payload(selfContained, capacity);
30
- }
31
-
32
- write(payload: Payload) {
33
- this.encode(payload.selfContained, payload.buffer);
34
- }
35
-
36
- abstract encode(selfContained:boolean, buffer: ByteBuffer): void;
37
- }
38
-
39
- class FrameEncoderUnprotected extends FrameEncoder {
40
-
41
- get allocator(): PayloadAllocator {
42
- return (capacity: number, selfContained = true) => new Payload(selfContained, capacity, HEADER_LENGTH);
43
- }
44
-
45
- encode(selfContained: boolean, frame: ByteBuffer) {
46
- const frameLength = frame.remaining;
47
- const dataLength = frameLength - HEADER_LENGTH;
48
- if (dataLength >= 1 << 17) {
49
- throw new Error(`maximum frame size 128KiB exceeded: ${dataLength}`);
50
- }
51
- writeHeader(frame, selfContained, dataLength);
52
- }
53
- }
54
-
55
- class FrameEncoderCrc extends FrameEncoder {
56
- get allocator(): PayloadAllocator {
57
- return (capacity: number, selfContained = true) => new Payload(selfContained, capacity, HEADER_LENGTH, TRAILER_LENGTH);
58
- }
59
-
60
- encode(selfContained: boolean, frame: ByteBuffer) {
61
- try {
62
- const frameLength = frame.remaining;
63
- const dataLength = frameLength - HEADER_AND_TRAILER_LENGTH;
64
- if (dataLength >= 1 << 17) {
65
- throw new Error(`maximum frame size 128KiB exceeded: ${dataLength}`);
66
- }
67
- writeHeader(frame, selfContained, dataLength);
68
- let frameCrc = computeCrc32(frame, HEADER_LENGTH, HEADER_LENGTH + dataLength);
69
- if (frame.order === 'big-endian') {
70
- frameCrc = reverseBytes32(frameCrc)
71
- }
72
- frame.limit = frameLength;
73
- frame.setInt32(frameLength - TRAILER_LENGTH, frameCrc);
74
- frame.position = 0;
75
-
76
- }
77
- catch (e) {
78
- // frame.release();
79
- throw e;
80
- }
81
- }
82
- }
83
-
84
- class Payload {
85
- readonly selfContained: boolean;
86
- readonly buffer: ByteBuffer;
87
- readonly headerLength: number;
88
- readonly trailerLength: number;
89
- private _finished = false;
90
-
91
- constructor(selfContained: boolean, payloadLength: number, headerLength: number = 0, trailerLength = 0) {
92
- this.selfContained = selfContained;
93
- this.headerLength = headerLength;
94
- this.trailerLength = trailerLength;
95
- this.buffer = allocate(payloadLength + headerLength + trailerLength);
96
- this.buffer.position = headerLength;
97
- this.buffer.limit = this.buffer.capacity - trailerLength;
98
- }
99
-
100
- get length(): number {
101
- if (this._finished) {
102
- throw new Error('already finished');
103
- }
104
- return this.buffer.position - this.headerLength;
105
- }
106
-
107
- get remaining(): number {
108
- if (this._finished) {
109
- throw new Error('already finished');
110
- }
111
- return this.buffer.remaining;
112
- }
113
-
114
- trim(length: number): void {
115
- if (this._finished) {
116
- throw new Error('already finished');
117
- }
118
- this.buffer.position = length + this.headerLength;
119
- }
120
-
121
- finish() {
122
- if (this._finished) {
123
- throw new Error('already finished');
124
- }
125
- this._finished = true;
126
- this.buffer.limit = this.buffer.position + this.trailerLength;
127
- this.buffer.position = 0;
128
- }
129
-
130
- release() {
131
-
132
- }
133
- }
134
-
135
- export type {Payload};
136
- export type PayloadAllocator = (capacity: number, selfContained?: boolean) => Payload;
137
- export type {FrameEncoder};
138
- export const encoder: FrameEncoder = new FrameEncoderCrc();
@@ -1,143 +0,0 @@
1
- import {type Address} from '../cluster/Address.ts';
2
- import {ByteBufferInput, ByteBufferOutput} from '../io/VersionedSerializer.ts';
3
- import {addressSerializer} from './AddressSerializer.ts'
4
- import {allocate, type ByteBuffer} from '../utils/buffer.ts';
5
- import {computeCrc32} from '../utils/crc.ts';
6
-
7
-
8
- /**
9
- * The initial message sent when a node creates a connection to a remote node.
10
- * - Magic
11
- * - Flags
12
- * - Version
13
- * - Broadcast Address
14
- *
15
- */
16
-
17
-
18
- export type AcceptVersions = Readonly<{min: number, max: number}>
19
-
20
- const FramingTypes = {
21
- UNPROTECTED: 0,
22
- // LZ4: 1
23
- CRC: 2
24
- }
25
- export type Framing = keyof typeof FramingTypes;
26
-
27
- const MIN_LENGTH = 8;
28
- const ACCEPT_MAX_LENGTH = 12;
29
- const INITIATE_MAX_LENGTH = 12 + addressSerializer.MAX_SIZE;
30
-
31
- function getBits(packed: number, start: number, count: number): number {
32
- return (packed >>> start) & ~(-1 << count);
33
- }
34
-
35
- export class Initiate {
36
- readonly from: Address;
37
- readonly framing: Framing;
38
- readonly acceptVersions: AcceptVersions;
39
- constructor(from: Address, framing: Framing, acceptVersions: AcceptVersions) {
40
- this.from = from;
41
- this.framing = framing;
42
- this.acceptVersions = acceptVersions;
43
- }
44
-
45
- private encodeFlags(): number {
46
- let flags = 0;
47
- flags |= 0x2; // MESSAGING SMALL
48
- flags |= (FramingTypes[this.framing] & 0x1) << 2 | (FramingTypes[this.framing] & 0x2) << 3;
49
- flags |= this.acceptVersions.min << 8;
50
- flags |= this.acceptVersions.min << 16;
51
- flags |= this.acceptVersions.max << 24;
52
- return flags;
53
- }
54
-
55
- encode(): ByteBuffer {
56
- const buffer = allocate(INITIATE_MAX_LENGTH);
57
- const out = new ByteBufferOutput(buffer);
58
- out.writeUint32(0xCA552DFA);
59
- out.writeUint32(this.encodeFlags());
60
- addressSerializer.serialize(this.from, out, this.acceptVersions.min);
61
- out.writeUint32(computeCrc32(buffer, 0, buffer.position));
62
- buffer.flip();
63
- return buffer;
64
- }
65
-
66
- static maybeDecode(buffer: ByteBuffer): Initiate | undefined {
67
- if (buffer.remaining < MIN_LENGTH) {
68
- return;
69
- }
70
- const position = buffer.position;
71
- const input = new ByteBufferInput(buffer, false);
72
- const magic = input.readInt32();
73
-
74
- const flags = input.readInt32();
75
- if (getBits(flags, 8, 8) < 12) {
76
- return;
77
- }
78
-
79
- const minVersion = getBits(flags, 16, 8);
80
- const maxVersion = getBits(flags, 24, 8);
81
-
82
- if (maxVersion < 12) {
83
- return;
84
- }
85
-
86
- const framingBits = getBits(flags, 2, 1) | (getBits(flags, 4, 1) << 1);
87
- const framing = framingBits === 0 ? 'UNPROTECTED' : framingBits === 2 ? 'CRC': undefined;
88
- const stream = getBits(flags, 3, 1) === 1;
89
-
90
- const from = addressSerializer.deserialize(input, minVersion);
91
-
92
- const computed = computeCrc32(buffer, position, position + buffer.position);
93
- const read = input.readInt32();
94
- if (computed !== read) {
95
- throw new Error('crc32 mismatch');
96
- }
97
-
98
- return new Initiate(from, framing, {min: minVersion, max: maxVersion});
99
- }
100
- }
101
-
102
- export class Accept {
103
- readonly useMessagingVersion: number;
104
- readonly maxMessagingVersion: number;
105
-
106
- constructor(useMessagingVersion: number, maxMessagingVersion: number) {
107
- this.useMessagingVersion = useMessagingVersion;
108
- this.maxMessagingVersion = maxMessagingVersion;
109
- }
110
-
111
- encode(): ByteBuffer {
112
- const buffer = allocate(ACCEPT_MAX_LENGTH);
113
- const out = new ByteBufferOutput(buffer);
114
- out.writeUint32(this.maxMessagingVersion);
115
- out.writeUint32(this.useMessagingVersion);
116
- out.writeUint32(computeCrc32(buffer, 0, 8));
117
- buffer.flip();
118
- return buffer;
119
- }
120
- static maybeDecode(buffer: ByteBuffer): Accept | undefined {
121
- const position = buffer.position;
122
- if (buffer.remaining < 4) {
123
- return;
124
- }
125
- const maxMessagingVersion = buffer.getUint32();
126
- if (maxMessagingVersion < 12) {
127
- return;
128
- }
129
-
130
- if (buffer.remaining < 8) {
131
- buffer.position = position;
132
- return;
133
- }
134
- const useMessagingVersion = buffer.getUint32();
135
-
136
- const computed = computeCrc32(buffer, position, position + 8);
137
- const read = buffer.getUint32();
138
- if (computed !== read) {
139
- throw new Error('crc32 mismatch');
140
- }
141
- return new Accept(useMessagingVersion, maxMessagingVersion);
142
- }
143
- }
@@ -1,108 +0,0 @@
1
- import {type Server, type Socket} from 'node:net';
2
- import type {Address} from '../cluster/Address.ts';
3
- import {deferred, type DeferredPromise} from '../utils/promise.ts';
4
- import getLogger from '../logging.ts';
5
- import {bind} from './InboundConnectionInitiator.ts';
6
- import type {AcceptVersions} from './HandshakeProtocol.ts';
7
- import type {FrameDecoder} from './FrameDecoder.ts';
8
-
9
- const logger = getLogger('net.inbound');
10
-
11
- export type InboundConnectionSettings = {
12
- bindAddress: Address,
13
- handlers: (from: Address) => { handle: (decoder: FrameDecoder, socket: Socket, version: number) => void },
14
- acceptVersions?: AcceptVersions,
15
- handshakeTimeout?: number,
16
- };
17
-
18
- export class InboundSocket {
19
- readonly settings: InboundConnectionSettings;
20
- private listen: Server;
21
- private binding: DeferredPromise<Server>;
22
- private closedBeforeOpen: boolean;
23
- private closePromise: Promise<void>;
24
-
25
- private readonly connections: Socket[] = [];
26
-
27
- constructor(settings: InboundConnectionSettings) {
28
- this.settings = settings;
29
- }
30
-
31
- async open(): Promise<void> {
32
- if (this.listen) {
33
- return;
34
- }
35
- if (this.binding) {
36
- await this.binding.promise;
37
- return;
38
- }
39
- if (this.closedBeforeOpen) {
40
- throw new Error("Socket closed before open");
41
- }
42
- this.binding = bind(this.settings, this.connections);
43
-
44
- const d = deferred<void>();
45
- this.binding.promise
46
- .catch((reason) => {
47
- delete this.binding;
48
- d.failure(reason);
49
- })
50
- .then((server: Server) => {
51
- this.listen = server;
52
- delete this.binding;
53
- d.success();
54
- })
55
- await d.promise;
56
- }
57
-
58
- close(shutdownListeners?: () => void): Promise<void> {
59
-
60
- const done = deferred<void>();
61
-
62
- const close = () => {
63
- const closing = [];
64
- if (this.listen !== undefined) {
65
- closing.push(new Promise<void>((resolve, reject) => {
66
- this.listen.close((err?) => {
67
- if (err) {
68
- reject(err);
69
- } else {
70
- resolve();
71
- }
72
- });
73
- }));
74
- }
75
- this.connections.forEach((socket) => {
76
- closing.push(new Promise<void>((resolve, _reject) => {
77
- socket.end(resolve);
78
- }));
79
- });
80
- Promise.all(closing)
81
- .then(() => {
82
- done.success();
83
- }).catch((err) => {
84
- done.failure(err);
85
- });
86
- };
87
-
88
- if (this.listen === undefined && this.binding === undefined) {
89
- this.closedBeforeOpen = true;
90
- return Promise.resolve();
91
- }
92
- if (this.closePromise !== undefined) {
93
- return this.closePromise;
94
- }
95
- this.closePromise = done.promise;
96
-
97
- if (this.listen !== undefined) {
98
- close();
99
- } else {
100
- this.binding.cancel();
101
- this.binding.promise.finally(() => close())
102
- }
103
-
104
- return done.promise;
105
-
106
- }
107
-
108
- }