@interopio/bridge 0.0.1-alpha → 0.0.3-beta

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 (84) hide show
  1. package/bin/bridge.js +1 -1
  2. package/dist/main.js +2139 -0
  3. package/dist/main.js.map +7 -0
  4. package/package.json +9 -6
  5. package/gen/instance/GeneratedBuildInfo.ts +0 -4
  6. package/src/cluster/Address.ts +0 -57
  7. package/src/cluster/Cluster.ts +0 -13
  8. package/src/cluster/Endpoint.ts +0 -5
  9. package/src/cluster/Member.ts +0 -9
  10. package/src/cluster/MembershipListener.ts +0 -6
  11. package/src/config/Config.ts +0 -100
  12. package/src/config/DiscoveryConfig.ts +0 -21
  13. package/src/config/Duration.ts +0 -168
  14. package/src/config/KubernetesConfig.ts +0 -7
  15. package/src/config/NamedDiscoveryConfig.ts +0 -17
  16. package/src/config/Properties.ts +0 -49
  17. package/src/config/index.ts +0 -1
  18. package/src/discovery/SimpleDiscoveryNode.ts +0 -14
  19. package/src/discovery/index.ts +0 -207
  20. package/src/discovery/multicast/MulticastDiscoveryStrategy.ts +0 -141
  21. package/src/discovery/multicast/MulticastDiscoveryStrategyFactory.ts +0 -30
  22. package/src/discovery/multicast/MulticastProperties.ts +0 -4
  23. package/src/discovery/settings.ts +0 -37
  24. package/src/error/RequestFailure.ts +0 -48
  25. package/src/gossip/ApplicationState.ts +0 -48
  26. package/src/gossip/EndpointState.ts +0 -141
  27. package/src/gossip/FailureDetector.ts +0 -235
  28. package/src/gossip/Gossiper.ts +0 -1133
  29. package/src/gossip/HeartbeatState.ts +0 -66
  30. package/src/gossip/Messenger.ts +0 -130
  31. package/src/gossip/VersionedValue.ts +0 -59
  32. package/src/index.ts +0 -3
  33. package/src/instance/AddressPicker.ts +0 -245
  34. package/src/instance/BridgeNode.ts +0 -141
  35. package/src/instance/ClusterTopologyIntentTracker.ts +0 -4
  36. package/src/io/VersionedSerializer.ts +0 -230
  37. package/src/io/util.ts +0 -117
  38. package/src/kubernetes/DnsEndpointResolver.ts +0 -70
  39. package/src/kubernetes/KubernetesApiEndpointResolver.ts +0 -111
  40. package/src/kubernetes/KubernetesApiProvider.ts +0 -75
  41. package/src/kubernetes/KubernetesClient.ts +0 -264
  42. package/src/kubernetes/KubernetesConfig.ts +0 -130
  43. package/src/kubernetes/KubernetesDiscoveryStrategy.ts +0 -30
  44. package/src/kubernetes/KubernetesDiscoveryStrategyFactory.ts +0 -71
  45. package/src/kubernetes/KubernetesEndpointResolver.ts +0 -43
  46. package/src/kubernetes/KubernetesProperties.ts +0 -22
  47. package/src/license/BridgeLicenseValidator.ts +0 -19
  48. package/src/license/LicenseValidator.ts +0 -114
  49. package/src/license/types.ts +0 -40
  50. package/src/logging.ts +0 -22
  51. package/src/main.mts +0 -53
  52. package/src/net/Action.ts +0 -143
  53. package/src/net/AddressSerializer.ts +0 -44
  54. package/src/net/ByteBufferAllocator.ts +0 -27
  55. package/src/net/FrameDecoder.ts +0 -314
  56. package/src/net/FrameEncoder.ts +0 -138
  57. package/src/net/HandshakeProtocol.ts +0 -143
  58. package/src/net/InboundConnection.ts +0 -108
  59. package/src/net/InboundConnectionInitiator.ts +0 -150
  60. package/src/net/InboundMessageHandler.ts +0 -377
  61. package/src/net/InboundSink.ts +0 -38
  62. package/src/net/Message.ts +0 -428
  63. package/src/net/OutboundConnection.ts +0 -1141
  64. package/src/net/OutboundConnectionInitiator.ts +0 -76
  65. package/src/net/RequestCallbacks.ts +0 -148
  66. package/src/net/ResponseHandler.ts +0 -30
  67. package/src/net/ShareableBytes.ts +0 -125
  68. package/src/net/internal/AsyncResourceExecutor.ts +0 -464
  69. package/src/net/internal/AsyncSocketPromise.ts +0 -37
  70. package/src/net/internal/channel/ChannelHandlerAdapter.ts +0 -99
  71. package/src/net/internal/channel/types.ts +0 -188
  72. package/src/utils/bigint.ts +0 -23
  73. package/src/utils/buffer.ts +0 -434
  74. package/src/utils/clock.ts +0 -148
  75. package/src/utils/collections.ts +0 -283
  76. package/src/utils/crc.ts +0 -39
  77. package/src/utils/internal/IpAddressUtil.ts +0 -161
  78. package/src/utils/memory/BufferPools.ts +0 -40
  79. package/src/utils/network.ts +0 -130
  80. package/src/utils/promise.ts +0 -38
  81. package/src/utils/uuid.ts +0 -5
  82. package/src/utils/vint.ts +0 -238
  83. package/src/version/MemberVersion.ts +0 -42
  84. 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
- }