Skip to content

Release/16 mar2026#194

Merged
avinash-newrelic merged 39 commits intomasterfrom
release/16MAR2026
Mar 31, 2026
Merged

Release/16 mar2026#194
avinash-newrelic merged 39 commits intomasterfrom
release/16MAR2026

Conversation

@avinash-newrelic
Copy link
Copy Markdown
Collaborator

No description provided.

mlychndnnr and others added 30 commits February 24, 2026 15:45
Add QOE_AGGREGATE action name and kpi.* attribute constants to
NRVideoDefs.h. Add qoeAggregateEnabled, qoeAggregateIntervalMultiplier,
and isQoeAggregateEnabled to NRVAVideoConfiguration for controlling
QoE event frequency relative to harvest cycles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce NRQoEAggregator to compute Quality of Experience metrics:
- Time-weighted average bitrate and peak bitrate tracking
- Rebuffering ratio from connection-type buffer events
- Startup time (timeSinceRequested minus pre-roll ad duration)
- Startup and playback failure flags

Uses a static dispatch table for action routing and @synchronized
for thread safety. Reads fully-assembled attributes from the tracker
pipeline (no parallel state or direct player API calls).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add qoeEventProvider callback and enqueueFinalQoeEvent to
NRVAHarvestManager. QoE events are generated at harvest time
(not heartbeat time) and injected directly into the batch array,
bypassing the crash-safe buffer.

Key design:
- Provider block called only when batch contains VideoAction events
- Multiplier formula (count-1)%N controls QoE frequency
- enqueueFinalQoeEvent accepts pre-built events from sendEnd to
  avoid race conditions with tracker thread cleanup
- pendingFinalQoe takes priority and auto-clears the provider

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NRVideoTracker changes:
- Initialize QoE aggregator when feature is enabled
- Snapshot content event attributes in preSendAction for QoE reuse
- Register qoeEventProvider block at sendStart (content path)
- Build final QoE eagerly at sendEnd and enqueue via
  enqueueFinalQoeEvent to avoid race with aggregator reset
- buildQoeEvent composes attributes from lastContentEventAttributes
  (filtering timeSince*/bufferType) overlaid with KPI metrics

NRVAVideo facade:
- Add setQoeEventProvider and enqueueFinalQoeEvent pass-throughs
- Add isQoeAggregateEnabled for tracker feature check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dead CDN URLs for Sintel and Airshow with working streams:
- Sintel -> Apple bipbop HEVC test stream (~30 min adaptive VOD)
- Airshow -> Akamai live HLS test stream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ll others

The previous implementation only counted "connection"-type buffers. Android and
JS SDKs use a simpler approach: skip the first CONTENT_BUFFER_END (initial
buffer) and accumulate all subsequent ones regardless of bufferType. This aligns
rebuffering metrics across all three platforms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…upError/hadPlaybackError

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ering

Use explicit bufferType check rather than skipping the first CONTENT_BUFFER_END
by position. This is more correct — it skips the actual initial buffer type
regardless of event ordering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align with Android and JS SDKs which emit unprefixed attribute names
(e.g. startupTime, not kpi.startupTime). QOE_PREFIX set to empty string.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… the same viewId as their content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace blocklist approach with strict whitelist of 19 context attributes
carried over from the last content event. Removes 17 attributes not
produced by the iOS video core (asn, device, page, etc.).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d centralized KPI keys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tegration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…by session flag

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on attributes to QoE whitelist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 tests covering NRQoEAggregator KPI computation (startup time,
bitrate tracking, rebuffering skip-first logic, error flags, reset)
and NRVAHarvestManager QoE integration (multiplier gate, dirty check,
pending final QoE priority).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix updatePlayTime() to accumulate ad vs content playtime separately
- Fix getAttributes() to use totalAdPlaytime for ad events, totalPlaytime for content events
- Remove double-counting logic in sendEnd() for ad playtime
- Remove unnecessary totalPreRollAdTime from CONTENT_START attributes
- Consolidate playtime logic within existing ad/content conditional blocks

This resolves the bug where totalPlaytime exceeded contentPlayhead due to
ad playtime contaminating content playtime measurements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Only accumulate content playtime after CONTENT_START to prevent pre-roll ad time from contaminating totalPlaytime
- Fix live detection race condition by checking item status before updating isLive property
- Clean up code formatting

This resolves the issue where totalPlaytime was showing 614s instead of 600s due to ~14s contamination from pre-roll ad tracking during CONTENT_REQUEST phase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change ad events to use correct field name 'totalAdPlaytime' instead of 'totalPlaytime'
- Prevents ad playtime from contaminating content playtime field
- Removes confusion between ad and content playtime tracking

This resolves the issue where ad events were incorrectly overwriting the
totalPlaytime field with ad playtime values, causing field contamination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move totalPreRollAdTime tracking to QoE aggregator internal state
- Add setTotalPreRollAdTime method to provide clean interface
- Remove dependency on passing totalPreRollAdTime through event attributes
- Prevent NRDB contamination by keeping internal data internal
- Fix startupTime calculation: timeSinceRequested - totalPreRollAdTime

This resolves the issue where startupTime was showing 16+ seconds instead of
the correct ~7 seconds due to missing totalPreRollAdTime subtraction. The QoE
aggregator now manages its own state instead of relying on external attributes.

Benefits:
- Clean architecture: aggregator owns its internal state
- Future-proof: core data remains on tracker for other use cases
- No NRDB risk: internal calculations don't leak to database
- Modular: QoE can be disabled without losing core tracking data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple fixes to resolve totalPlaytime accuracy and application crashes:

1. **Fix EXC_BAD_ACCESS crash in setTotalPreRollAdTime**:
   - Replace property with instance variable for safer memory access
   - Add nil checks to prevent crashes on deallocated aggregator
   - Use direct variable access instead of property setter/getter

2. **Fix totalPlaytime session-based tracking**:
   - Restore hasContentStarted flag for proper content session boundaries
   - Change from isStarted (playing state) to hasContentStarted (session state)
   - Now accumulates time during entire content session: playing, paused, buffering, seeking
   - Prevents pre-roll ad time contamination while capturing full engagement time

3. **Fix CONTENT_END totalPlaytime accuracy**:
   - Use live calculation only for CONTENT_END to capture final unflushed playtime
   - Regular content events use efficient stored values for performance
   - Consistent totalPlaytime values between QOE_AGGREGATE and CONTENT_END

4. **Simplify sendEnd logic**:
   - Remove unnecessary complexity from final QoE generation
   - Session-based tracking naturally handles timing without race conditions
   - Clean, maintainable code with single source of truth

Expected results:
- No more application crashes when clicking video links
- totalPlaytime ≈ contentDuration (~101s) when video watched completely
- Consistent, non-regressing totalPlaytime values across all events
- Proper separation between ad and content playtime tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves race condition where multiple QOE events could be generated
in the same harvest cycle at boundary conditions (e.g., CONTENT_END).

- Remove duplicate QOE_AGGREGATE events from batch before adding latest
- Ensure only one authoritative QOE event per harvest cycle
- Add debug logging for duplicate detection
- Handle boundary conditions without modifying provider pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ametku and others added 9 commits March 19, 2026 16:29
Replace broken single global QoE provider with multi-tracker collection
system. Harvest manager now discovers and collects QoE from all active
video trackers independently, ensuring each video session reports QoE
correctly instead of only the last active tracker.

- Remove legacy qoeEventProvider system from harvest manager
- Add per-tracker cycle management and session lifecycle tracking
- Implement proper dirty checking to avoid duplicate QoE events
- Standardize logging to use NRVA_DEBUG_LOG consistently

Fixes multi-video QoE reporting where previously only one tracker's
metrics were sent during harvest cycles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each tracker manages its own cycle count independently, making the global counter redundant and potentially confusing.
fix: resolve QoE deduplication issue in multi-video scenarios
fix: Reset timeSince started and requested attr
@avinash-newrelic avinash-newrelic merged commit aa761f8 into master Mar 31, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants