Skip to content

Commit d89a518

Browse files
committed
LiveQueries auto-init fix | live queries data expansion
1 parent b6c0708 commit d89a518

6 files changed

Lines changed: 870 additions & 283 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,13 +856,17 @@ Main agent singleton instance.
856856

857857
### v1.0.19 (Bug Fixes & Code Quality)
858858

859+
- **Fix LiveQueriesCollector showing 0 observers and 0 metrics** - Completely rewrote observer interception. The previous approach wrapped `Mongo.Collection.prototype.find` to patch `cursor.observe`/`cursor.observeChanges` on each returned cursor instance, but this failed because: (1) in Meteor 3.x, `observeChanges` is async (returns a Promise via `MongoConnection._observeChanges`) but the wrapper treated it synchronously; (2) the per-cursor instance patching was fragile. Now hooks directly into `MongoInternals.Connection.prototype._observeChanges` — the single async bottleneck ALL server-side observers funnel through. Uses a two-phase tracking approach: `_createObserverData()` creates a provisional observer record BEFORE calling the original `_observeChanges`, so that wrapped `added`/`changed`/`removed` callbacks can count initial documents arriving during the await. `_finalizeObserver()` then links the handle's multiplexer and driver type after the await. Deduplicates by multiplexer identity (not query hash) so observers sharing a Meteor ObserveMultiplexer are counted as one server-side resource with multiple handlers. Falls back to `Collection.prototype.find` wrapping when `MongoInternals` is unavailable.
860+
- **Fix LiveQueriesCollector config missing from DEFAULT_CONFIG** - `collectLiveQueries`, `liveQueriesInterval`, and `liveQueriesPerformanceThresholds` were defined in the `SkySignalAgent` constructor but missing from `config.js` `DEFAULT_CONFIG`. Since `mergeConfig()` spreads `DEFAULT_CONFIG` first, these values were always overwritten to `undefined`, silently disabling live query collection.
859861
- **Fix container memory usage reporting >100%** - `SystemMetricsCollector` previously calculated container memory as `processMemory.rss / constrainedMemory * 100`, which could exceed 100% because RSS (Resident Set Size) includes shared library pages, memory-mapped files, and kernel page cache that don't count against the container's cgroup memory limit. Now uses `process.availableMemory()` (Node 19+), which reads directly from the cgroup memory controller and accounts for reclaimable buffers, to compute usage as `(constrainedMemory - availableMemory) / constrainedMemory * 100`. Falls back to `heapUsed / constrainedMemory * 100` on older Node versions. This aligns reported memory with what container orchestrators (e.g., Meteor Galaxy) actually report.
860862
- **Fix observer stop logging crash** - `LiveQueriesCollector._wrapHandle()` used `this._log()` inside a regular `function()` callback where `this` referred to the handle object, not the collector instance. Changed to `self._log()` to use the captured closure variable. Previously, calling `handle.stop()` would throw `TypeError: this._log is not a function`, silently preventing observer lifecycle metrics from being recorded.
861863
- **Fix P95 percentile off-by-one** - `MongoPoolCollector`, `DnsTimingCollector`, and `DiagnosticsChannelCollector` all used `Math.floor(count * 0.95)` to index into a sorted array, which overshoots the true 95th percentile by one position (e.g., for 100 items, returns the 96th element instead of the 95th). Changed to `Math.ceil(count * p) - 1` across all three collectors. Extracted to shared `percentile()` utility in `lib/utils/percentile.js`.
862864
- **Fix MongoPoolCollector.stop() killing other event listeners** - `stop()` called `client.removeAllListeners(eventName)` for each pool event, which removed ALL listeners for that event — including those registered by the application or other collectors. Now stores individual handler references in `start()` and calls `client.removeListener(eventName, handler)` in `stop()` to remove only the collector's own handlers.
863865
- **Fix circular buffer read after wrap-around** - `MongoPoolCollector._calculateCheckoutMetrics()` used `checkoutSamples.slice(0, count)` to extract samples, which returns incorrect data after the circular buffer wraps (old data mixed with new). Now correctly reads from the current write index forward using modular arithmetic to reconstruct the proper time-ordered sequence.
864866
- **Shared percentile utility** - Extracted percentile calculation to `lib/utils/percentile.js` with `percentile(sorted, p)` and `percentiles(values)` functions, replacing duplicated math in `MongoPoolCollector`, `DnsTimingCollector`, and `DiagnosticsChannelCollector`.
865867
- **Shared buffer eviction utility** - Extracted array trimming to `lib/utils/buffer.js` with `trimToMaxSize(array, maxSize)`, replacing duplicated `splice(0, length - max)` patterns in `DnsTimingCollector`, `DiagnosticsChannelCollector`, and `MongoPoolCollector._recordPoolWaitTime`.
868+
- **Leak-detection field tests** - Added 19 unit tests (`LiveQueriesCollector.leakFields.test.js`) verifying the collector produces correct values for fields used by the server-side `ObserverLeakDetectionService`: `_wrapCallbacks` correctly increments `liveUpdateCount` and `lastActivityAt` only after initial load completes (not during the initial document fetch), `_wrapHandle` calculates `observerLifespan` in seconds on stop, and `_createObserverData` initializes all leak-relevant fields to safe defaults. These tests ensure the agent emits the data contract that leak detection heuristics (inactive observers, long-lived stale observers, orphaned observers) depend on.
869+
- **Remove stale `_generateQuerySignature` tests** - Deleted 5 tests for `_generateQuerySignature` in `LiveQueriesCollector.test.js` that were left behind when the method was removed during the v1.0.19 observer interception rewrite. These tests were failing with `TypeError: collector._generateQuerySignature is not a function`.
866870

867871
### v1.0.18 (Container-Aware Metrics)
868872

0 commit comments

Comments
 (0)