fix(audience): stop mutating queued events on consent change (SDK-647)#814
Merged
Merged
Conversation
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.
Audience SDK — Build Size
SDK Size = build minus empty app. Change = vs baseline. Fails if any platform exceeds its absolute size limit. |
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
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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(anduserId) 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 stripsuserId/ dropsidentify+aliasfrom already-queued events.EventQueue.ApplyAnonymousDowngradeand theDiskStoredowngrade-rewrite helpers.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
Noneno 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
ImmutableAudienceTests,DiskStoreTests,SessionTests,EventQueueTests)SampleAppLiveFireTests)com.immutable.audience) passes with 0 errorsDraft for review.