@naylence/runtime 0.3.5-test.954 → 0.3.5-test.955
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.
- package/dist/browser/index.cjs +103 -18
- package/dist/browser/index.mjs +103 -18
- package/dist/cjs/naylence/fame/channel/flow-controller.js +38 -1
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +50 -1
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/channel/flow-controller.js +38 -1
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +50 -1
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +103 -18
- package/dist/node/index.mjs +103 -18
- package/dist/node/node.cjs +103 -18
- package/dist/node/node.mjs +103 -18
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +3 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.FlowController = void 0;
|
|
27
27
|
const core_1 = require("@naylence/core");
|
|
28
|
+
const logging_js_1 = require("../util/logging.js");
|
|
29
|
+
const logger = (0, logging_js_1.getLogger)('naylence.fame.flow.flow_controller');
|
|
28
30
|
/**
|
|
29
31
|
* Simple condition variable implementation for TypeScript/Node.js
|
|
30
32
|
* Similar to Python's asyncio.Condition
|
|
@@ -150,8 +152,17 @@ class FlowController {
|
|
|
150
152
|
// clamp into [0, initialWindow]
|
|
151
153
|
const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
|
|
152
154
|
this.credits.set(flowId, newBalance);
|
|
155
|
+
const crossedZero = prev <= 0 && newBalance > 0;
|
|
156
|
+
logger.debug('flow_controller_add_credits', {
|
|
157
|
+
flow_id: flowId,
|
|
158
|
+
delta,
|
|
159
|
+
prev_balance: prev,
|
|
160
|
+
new_balance: newBalance,
|
|
161
|
+
initial_window: this.initialWindow,
|
|
162
|
+
crossed_zero: crossedZero,
|
|
163
|
+
});
|
|
153
164
|
// wake waiters only if we crossed the zero boundary
|
|
154
|
-
if (
|
|
165
|
+
if (crossedZero) {
|
|
155
166
|
this.wakeWaiters(flowId);
|
|
156
167
|
}
|
|
157
168
|
return newBalance;
|
|
@@ -162,11 +173,27 @@ class FlowController {
|
|
|
162
173
|
async acquire(flowId) {
|
|
163
174
|
this.ensureFlow(flowId);
|
|
164
175
|
const condition = this.conditions.get(flowId);
|
|
176
|
+
logger.debug('flow_controller_acquire_attempt', {
|
|
177
|
+
flow_id: flowId,
|
|
178
|
+
current_balance: this.credits.get(flowId),
|
|
179
|
+
});
|
|
165
180
|
while (this.credits.get(flowId) <= 0) {
|
|
181
|
+
logger.debug('flow_controller_waiting_for_credit', {
|
|
182
|
+
flow_id: flowId,
|
|
183
|
+
});
|
|
166
184
|
await condition.wait();
|
|
185
|
+
logger.debug('flow_controller_woke_with_credit', {
|
|
186
|
+
flow_id: flowId,
|
|
187
|
+
balance_after_wake: this.credits.get(flowId),
|
|
188
|
+
});
|
|
167
189
|
}
|
|
168
190
|
const current = this.credits.get(flowId);
|
|
169
191
|
this.credits.set(flowId, current - 1);
|
|
192
|
+
logger.debug('flow_controller_credit_consumed', {
|
|
193
|
+
flow_id: flowId,
|
|
194
|
+
prev_balance: current,
|
|
195
|
+
remaining_balance: current - 1,
|
|
196
|
+
});
|
|
170
197
|
}
|
|
171
198
|
/**
|
|
172
199
|
* Consume *credits* immediately (non-blocking).
|
|
@@ -186,6 +213,12 @@ class FlowController {
|
|
|
186
213
|
const current = this.credits.get(flowId);
|
|
187
214
|
const remaining = Math.max(current - credits, 0);
|
|
188
215
|
this.credits.set(flowId, remaining);
|
|
216
|
+
logger.debug('flow_controller_consume', {
|
|
217
|
+
flow_id: flowId,
|
|
218
|
+
requested: credits,
|
|
219
|
+
prev_balance: current,
|
|
220
|
+
remaining_balance: remaining,
|
|
221
|
+
});
|
|
189
222
|
return remaining;
|
|
190
223
|
}
|
|
191
224
|
/**
|
|
@@ -206,6 +239,10 @@ class FlowController {
|
|
|
206
239
|
this.windowIds.delete(flowId);
|
|
207
240
|
this.credits.set(flowId, this.initialWindow);
|
|
208
241
|
this.wakeWaiters(flowId);
|
|
242
|
+
logger.debug('flow_controller_flow_reset', {
|
|
243
|
+
flow_id: flowId,
|
|
244
|
+
reset_balance: this.initialWindow,
|
|
245
|
+
});
|
|
209
246
|
}
|
|
210
247
|
/**
|
|
211
248
|
* Return `[windowId, flags]` for the next outbound envelope.
|
|
@@ -69,6 +69,7 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
69
69
|
? Math.floor(config.inboxCapacity)
|
|
70
70
|
: DEFAULT_INBOX_CAPACITY;
|
|
71
71
|
this.inbox = new bounded_async_queue_js_1.BoundedAsyncQueue(preferredCapacity);
|
|
72
|
+
this.inboxCapacity = preferredCapacity;
|
|
72
73
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
73
74
|
this.channel = new BroadcastChannel(this.channelName);
|
|
74
75
|
logger.debug('broadcast_channel_connector_created', {
|
|
@@ -128,15 +129,27 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
128
129
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
129
130
|
const accepted = this.inbox.tryEnqueue(payload);
|
|
130
131
|
if (accepted) {
|
|
132
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
133
|
+
source: 'listener',
|
|
134
|
+
enqueue_strategy: 'try',
|
|
135
|
+
payload_length: payload.byteLength,
|
|
136
|
+
});
|
|
131
137
|
return;
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
this.inbox.enqueue(payload);
|
|
141
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
142
|
+
source: 'listener',
|
|
143
|
+
enqueue_strategy: 'enqueue',
|
|
144
|
+
payload_length: payload.byteLength,
|
|
145
|
+
});
|
|
135
146
|
}
|
|
136
147
|
catch (error) {
|
|
137
148
|
if (error instanceof bounded_async_queue_js_1.QueueFullError) {
|
|
138
149
|
logger.warning('broadcast_channel_receive_queue_full', {
|
|
139
150
|
channel: this.channelName,
|
|
151
|
+
inbox_capacity: this.inboxCapacity,
|
|
152
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
140
153
|
});
|
|
141
154
|
}
|
|
142
155
|
else {
|
|
@@ -220,15 +233,25 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
220
233
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
221
234
|
const accepted = this.inbox.tryEnqueue(item);
|
|
222
235
|
if (accepted) {
|
|
236
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
237
|
+
enqueue_strategy: 'try',
|
|
238
|
+
item_type: this._describeInboxItem(item),
|
|
239
|
+
});
|
|
223
240
|
return;
|
|
224
241
|
}
|
|
225
242
|
}
|
|
226
243
|
this.inbox.enqueue(item);
|
|
244
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
245
|
+
enqueue_strategy: 'enqueue',
|
|
246
|
+
item_type: this._describeInboxItem(item),
|
|
247
|
+
});
|
|
227
248
|
}
|
|
228
249
|
catch (error) {
|
|
229
250
|
if (error instanceof bounded_async_queue_js_1.QueueFullError) {
|
|
230
251
|
logger.warning('broadcast_channel_push_queue_full', {
|
|
231
252
|
channel: this.channelName,
|
|
253
|
+
inbox_capacity: this.inboxCapacity,
|
|
254
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
232
255
|
});
|
|
233
256
|
throw error;
|
|
234
257
|
}
|
|
@@ -251,7 +274,11 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
251
274
|
});
|
|
252
275
|
}
|
|
253
276
|
async _transportReceive() {
|
|
254
|
-
|
|
277
|
+
const item = await this.inbox.dequeue();
|
|
278
|
+
this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
|
|
279
|
+
item_type: this._describeInboxItem(item),
|
|
280
|
+
});
|
|
281
|
+
return item;
|
|
255
282
|
}
|
|
256
283
|
async _transportClose(code, reason) {
|
|
257
284
|
logger.debug('broadcast_channel_transport_closing', {
|
|
@@ -305,6 +332,28 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
305
332
|
}
|
|
306
333
|
return rawOrEnvelope;
|
|
307
334
|
}
|
|
335
|
+
_describeInboxItem(item) {
|
|
336
|
+
if (item instanceof Uint8Array) {
|
|
337
|
+
return 'bytes';
|
|
338
|
+
}
|
|
339
|
+
if (item.envelope) {
|
|
340
|
+
return 'channel_message';
|
|
341
|
+
}
|
|
342
|
+
if (item.frame) {
|
|
343
|
+
return 'envelope';
|
|
344
|
+
}
|
|
345
|
+
return 'unknown';
|
|
346
|
+
}
|
|
347
|
+
logInboxSnapshot(event, extra = {}) {
|
|
348
|
+
logger.debug(event, {
|
|
349
|
+
channel: this.channelName,
|
|
350
|
+
connector_id: this.connectorId,
|
|
351
|
+
connector_state: this.state,
|
|
352
|
+
inbox_capacity: this.inboxCapacity,
|
|
353
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
354
|
+
...extra,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
308
357
|
_shouldSkipDuplicateAck(senderId, payload) {
|
|
309
358
|
const dedupKey = this._extractAckDedupKey(payload);
|
|
310
359
|
if (!dedupKey) {
|
package/dist/cjs/version.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This file is auto-generated during build - do not edit manually
|
|
3
|
-
// Generated from package.json version: 0.3.5-test.
|
|
3
|
+
// Generated from package.json version: 0.3.5-test.955
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.VERSION = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* The package version, injected at build time.
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
exports.VERSION = '0.3.5-test.
|
|
10
|
+
exports.VERSION = '0.3.5-test.955';
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
* flow at any time.
|
|
23
23
|
*/
|
|
24
24
|
import { FlowFlags } from '@naylence/core';
|
|
25
|
+
import { getLogger } from '../util/logging.js';
|
|
26
|
+
const logger = getLogger('naylence.fame.flow.flow_controller');
|
|
25
27
|
/**
|
|
26
28
|
* Simple condition variable implementation for TypeScript/Node.js
|
|
27
29
|
* Similar to Python's asyncio.Condition
|
|
@@ -147,8 +149,17 @@ export class FlowController {
|
|
|
147
149
|
// clamp into [0, initialWindow]
|
|
148
150
|
const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
|
|
149
151
|
this.credits.set(flowId, newBalance);
|
|
152
|
+
const crossedZero = prev <= 0 && newBalance > 0;
|
|
153
|
+
logger.debug('flow_controller_add_credits', {
|
|
154
|
+
flow_id: flowId,
|
|
155
|
+
delta,
|
|
156
|
+
prev_balance: prev,
|
|
157
|
+
new_balance: newBalance,
|
|
158
|
+
initial_window: this.initialWindow,
|
|
159
|
+
crossed_zero: crossedZero,
|
|
160
|
+
});
|
|
150
161
|
// wake waiters only if we crossed the zero boundary
|
|
151
|
-
if (
|
|
162
|
+
if (crossedZero) {
|
|
152
163
|
this.wakeWaiters(flowId);
|
|
153
164
|
}
|
|
154
165
|
return newBalance;
|
|
@@ -159,11 +170,27 @@ export class FlowController {
|
|
|
159
170
|
async acquire(flowId) {
|
|
160
171
|
this.ensureFlow(flowId);
|
|
161
172
|
const condition = this.conditions.get(flowId);
|
|
173
|
+
logger.debug('flow_controller_acquire_attempt', {
|
|
174
|
+
flow_id: flowId,
|
|
175
|
+
current_balance: this.credits.get(flowId),
|
|
176
|
+
});
|
|
162
177
|
while (this.credits.get(flowId) <= 0) {
|
|
178
|
+
logger.debug('flow_controller_waiting_for_credit', {
|
|
179
|
+
flow_id: flowId,
|
|
180
|
+
});
|
|
163
181
|
await condition.wait();
|
|
182
|
+
logger.debug('flow_controller_woke_with_credit', {
|
|
183
|
+
flow_id: flowId,
|
|
184
|
+
balance_after_wake: this.credits.get(flowId),
|
|
185
|
+
});
|
|
164
186
|
}
|
|
165
187
|
const current = this.credits.get(flowId);
|
|
166
188
|
this.credits.set(flowId, current - 1);
|
|
189
|
+
logger.debug('flow_controller_credit_consumed', {
|
|
190
|
+
flow_id: flowId,
|
|
191
|
+
prev_balance: current,
|
|
192
|
+
remaining_balance: current - 1,
|
|
193
|
+
});
|
|
167
194
|
}
|
|
168
195
|
/**
|
|
169
196
|
* Consume *credits* immediately (non-blocking).
|
|
@@ -183,6 +210,12 @@ export class FlowController {
|
|
|
183
210
|
const current = this.credits.get(flowId);
|
|
184
211
|
const remaining = Math.max(current - credits, 0);
|
|
185
212
|
this.credits.set(flowId, remaining);
|
|
213
|
+
logger.debug('flow_controller_consume', {
|
|
214
|
+
flow_id: flowId,
|
|
215
|
+
requested: credits,
|
|
216
|
+
prev_balance: current,
|
|
217
|
+
remaining_balance: remaining,
|
|
218
|
+
});
|
|
186
219
|
return remaining;
|
|
187
220
|
}
|
|
188
221
|
/**
|
|
@@ -203,6 +236,10 @@ export class FlowController {
|
|
|
203
236
|
this.windowIds.delete(flowId);
|
|
204
237
|
this.credits.set(flowId, this.initialWindow);
|
|
205
238
|
this.wakeWaiters(flowId);
|
|
239
|
+
logger.debug('flow_controller_flow_reset', {
|
|
240
|
+
flow_id: flowId,
|
|
241
|
+
reset_balance: this.initialWindow,
|
|
242
|
+
});
|
|
206
243
|
}
|
|
207
244
|
/**
|
|
208
245
|
* Return `[windowId, flags]` for the next outbound envelope.
|
|
@@ -66,6 +66,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
66
66
|
? Math.floor(config.inboxCapacity)
|
|
67
67
|
: DEFAULT_INBOX_CAPACITY;
|
|
68
68
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
69
|
+
this.inboxCapacity = preferredCapacity;
|
|
69
70
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
70
71
|
this.channel = new BroadcastChannel(this.channelName);
|
|
71
72
|
logger.debug('broadcast_channel_connector_created', {
|
|
@@ -125,15 +126,27 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
125
126
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
126
127
|
const accepted = this.inbox.tryEnqueue(payload);
|
|
127
128
|
if (accepted) {
|
|
129
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
130
|
+
source: 'listener',
|
|
131
|
+
enqueue_strategy: 'try',
|
|
132
|
+
payload_length: payload.byteLength,
|
|
133
|
+
});
|
|
128
134
|
return;
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
this.inbox.enqueue(payload);
|
|
138
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
139
|
+
source: 'listener',
|
|
140
|
+
enqueue_strategy: 'enqueue',
|
|
141
|
+
payload_length: payload.byteLength,
|
|
142
|
+
});
|
|
132
143
|
}
|
|
133
144
|
catch (error) {
|
|
134
145
|
if (error instanceof QueueFullError) {
|
|
135
146
|
logger.warning('broadcast_channel_receive_queue_full', {
|
|
136
147
|
channel: this.channelName,
|
|
148
|
+
inbox_capacity: this.inboxCapacity,
|
|
149
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
137
150
|
});
|
|
138
151
|
}
|
|
139
152
|
else {
|
|
@@ -217,15 +230,25 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
217
230
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
218
231
|
const accepted = this.inbox.tryEnqueue(item);
|
|
219
232
|
if (accepted) {
|
|
233
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
234
|
+
enqueue_strategy: 'try',
|
|
235
|
+
item_type: this._describeInboxItem(item),
|
|
236
|
+
});
|
|
220
237
|
return;
|
|
221
238
|
}
|
|
222
239
|
}
|
|
223
240
|
this.inbox.enqueue(item);
|
|
241
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
242
|
+
enqueue_strategy: 'enqueue',
|
|
243
|
+
item_type: this._describeInboxItem(item),
|
|
244
|
+
});
|
|
224
245
|
}
|
|
225
246
|
catch (error) {
|
|
226
247
|
if (error instanceof QueueFullError) {
|
|
227
248
|
logger.warning('broadcast_channel_push_queue_full', {
|
|
228
249
|
channel: this.channelName,
|
|
250
|
+
inbox_capacity: this.inboxCapacity,
|
|
251
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
229
252
|
});
|
|
230
253
|
throw error;
|
|
231
254
|
}
|
|
@@ -248,7 +271,11 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
248
271
|
});
|
|
249
272
|
}
|
|
250
273
|
async _transportReceive() {
|
|
251
|
-
|
|
274
|
+
const item = await this.inbox.dequeue();
|
|
275
|
+
this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
|
|
276
|
+
item_type: this._describeInboxItem(item),
|
|
277
|
+
});
|
|
278
|
+
return item;
|
|
252
279
|
}
|
|
253
280
|
async _transportClose(code, reason) {
|
|
254
281
|
logger.debug('broadcast_channel_transport_closing', {
|
|
@@ -302,6 +329,28 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
302
329
|
}
|
|
303
330
|
return rawOrEnvelope;
|
|
304
331
|
}
|
|
332
|
+
_describeInboxItem(item) {
|
|
333
|
+
if (item instanceof Uint8Array) {
|
|
334
|
+
return 'bytes';
|
|
335
|
+
}
|
|
336
|
+
if (item.envelope) {
|
|
337
|
+
return 'channel_message';
|
|
338
|
+
}
|
|
339
|
+
if (item.frame) {
|
|
340
|
+
return 'envelope';
|
|
341
|
+
}
|
|
342
|
+
return 'unknown';
|
|
343
|
+
}
|
|
344
|
+
logInboxSnapshot(event, extra = {}) {
|
|
345
|
+
logger.debug(event, {
|
|
346
|
+
channel: this.channelName,
|
|
347
|
+
connector_id: this.connectorId,
|
|
348
|
+
connector_state: this.state,
|
|
349
|
+
inbox_capacity: this.inboxCapacity,
|
|
350
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
351
|
+
...extra,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
305
354
|
_shouldSkipDuplicateAck(senderId, payload) {
|
|
306
355
|
const dedupKey = this._extractAckDedupKey(payload);
|
|
307
356
|
if (!dedupKey) {
|
package/dist/esm/version.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This file is auto-generated during build - do not edit manually
|
|
2
|
-
// Generated from package.json version: 0.3.5-test.
|
|
2
|
+
// Generated from package.json version: 0.3.5-test.955
|
|
3
3
|
/**
|
|
4
4
|
* The package version, injected at build time.
|
|
5
5
|
* @internal
|
|
6
6
|
*/
|
|
7
|
-
export const VERSION = '0.3.5-test.
|
|
7
|
+
export const VERSION = '0.3.5-test.955';
|