@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.
@@ -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 (prev <= 0 && newBalance > 0) {
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
- return await this.inbox.dequeue();
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) {
@@ -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.954
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.954';
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 (prev <= 0 && newBalance > 0) {
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
- return await this.inbox.dequeue();
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) {
@@ -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.954
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.954';
7
+ export const VERSION = '0.3.5-test.955';