Skip to content

fix(audience): stop mutating queued events on consent change (SDK-647)#814

Merged
nattb8 merged 2 commits into
mainfrom
feat/sdk-647-avoid-mutating-consent-queue-unity
Jul 9, 2026
Merged

fix(audience): stop mutating queued events on consent change (SDK-647)#814
nattb8 merged 2 commits into
mainfrom
feat/sdk-647-avoid-mutating-consent-queue-unity

Conversation

@JCSanPedro

Copy link
Copy Markdown
Contributor

Summary

Ports the web/pixel change from immutable/ts-immutable-sdk#2896 to the Unity Audience SDK, for the same ticket SDK-647.

A consent change now gates only future collection. Events already recorded keep the consentLevel (and userId) they were captured with. Under GDPR the applicable consent is the one in force at capture time, so there is no need to retroactively rewrite or purge already-queued events.

Changes

  • SetConsent(None) no longer purges the queue. Session teardown and the anonymous-id wipe (Identity.Reset) are unchanged, but previously-recorded events are kept and will be sent.
  • SetConsent(Full -> Anonymous) no longer strips userId / drops identify+alias from already-queued events.
  • Removed the now-dead EventQueue.ApplyAnonymousDowngrade and the DiskStore downgrade-rewrite helpers.
  • Updated unit + live-fire tests and stale comments to match.

Behaviour retained (by design)

The record-time consent gate in EnqueueChecked (EnqueueTrack / EnqueueIdentity) is kept. An in-flight event still finalises its consent at the moment it is enqueued - this is Unity's threading analog of stamping consent at capture time, and it never rewrites events already in the queue. The two concurrency stress tests (SetConsent_DowngradeToNone_StressTest_NoLeak, SetConsent_DowngradeToAnonymous_StressTest_NoUserIdLeak) still pass on this gate.

Behaviour change to flag for review

Revoking to None no longer discards unsent events - events captured under valid consent before the change are now flushed to the API. This is the intended consequence of the ticket (consent is determined at capture time), and mirrors the web/pixel PR. Please confirm this is acceptable.

Test plan

  • CI: Unity edit-mode tests (ImmutableAudienceTests, DiskStoreTests, SessionTests, EventQueueTests)
  • Live-fire sample-app tests (SampleAppLiveFireTests)
  • Standalone compile of the engine-free Core assembly (com.immutable.audience) passes with 0 errors

Draft for review.

Consent changes now gate only future collection; events already recorded
keep the consent level (and userId) they were captured under. Under GDPR
the applicable consent is the one in force at capture time, so there is no
need to retroactively rewrite or purge already-queued events.

- SetConsent(None) no longer purges the queue (session teardown and
  anonymous-id wipe are unchanged); previously-recorded events are sent.
- SetConsent(Full -> Anonymous) no longer strips userId / drops
  identify+alias from queued events.
- Remove now-dead EventQueue.ApplyAnonymousDowngrade and the DiskStore
  rewrite helpers.

The record-time consent gate in EnqueueChecked is retained: an in-flight
event still finalises its consent at the moment it is enqueued (Unity's
threading analog of stamping at capture time). It never rewrites events
already in the queue.
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Audience SDK — Build Size

Platform SDK Size Change
Android 0.36 / 20.00 MB +0.00 MB
Windows 0.16 / 20.00 MB +0.00 MB
iOS 8.54 / 20.00 MB +0.02 MB
macOS 0.90 / 20.00 MB +0.00 MB

SDK Size = build minus empty app. Change = vs baseline. Fails if any platform exceeds its absolute size limit.

@JCSanPedro JCSanPedro marked this pull request as ready for review July 8, 2026 23:04
@JCSanPedro JCSanPedro requested review from a team as code owners July 8, 2026 23:04
nattb8
nattb8 previously approved these changes Jul 9, 2026
…d-scheduling-dependent

The three SetConsent-vs-Track race tests relied on ManualResetEventSlim/Barrier
handoffs to make a tracker thread's enqueue land after SetConsent's state flip.
In practice the signalling thread always got a scheduling head start, so the
enqueue consistently completed before the flip -- failing deterministically
in CI regardless of iteration count. Replaced with a GatedEvent (IEvent whose
ToProperties blocks) that pins the race window precisely: Track snapshots
state and parks mid-flight, SetConsent runs to completion, then the tracker
is released, guaranteeing every enqueue lands after the flip.
@nattb8 nattb8 enabled auto-merge July 9, 2026 22:37
@nattb8 nattb8 merged commit 1e6fb1a into main Jul 9, 2026
54 of 56 checks passed
@nattb8 nattb8 deleted the feat/sdk-647-avoid-mutating-consent-queue-unity branch July 9, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants