Skip to content

fix: Rewrite AppLifeCycleManager onto Combine#95

Merged
abelonogov-ld merged 9 commits intomainfrom
andrey/app-lify-cycle2
Dec 12, 2025
Merged

fix: Rewrite AppLifeCycleManager onto Combine#95
abelonogov-ld merged 9 commits intomainfrom
andrey/app-lify-cycle2

Conversation

@abelonogov-ld
Copy link
Copy Markdown
Contributor

@abelonogov-ld abelonogov-ld commented Dec 12, 2025

To make AsyncStream be used correctly you need to create analog of publisher-subscription, which will turn code into similar to Combine. But why recreate Combine it is already exists


Note

Replaces AsyncStream/Broadcaster-based eventing with Combine publishers across lifecycle, session, and transport; updates consumers (logging, snapshot, exporter) and tests; adds cleanup and deadlock-safe dispatch.

  • Observability:
    • AppLifecycleManager: Replace events() AsyncStream with publisher() using PassthroughSubject; keep UIKit notification observers.
    • SessionManager: Switch to Combine subscription to lifecycle publisher(); expose publisher() for SessionInfo; async-notify on a dedicated queue to avoid deadlock.
    • EventQueue: Replace Broadcaster with PassthroughSubject; add publisher() for EventNotifyStatus and use it for overflow/available notifications.
    • AppLifecycleLogger: Replace async loop with Combine pipeline (map lifecycle events → logs) and manage via AnyCancellable.
  • Session Replay:
    • SnapshotTaker: Subscribe to EventQueue.publisher() and AppLifecycleManager.publisher() on main queue to control start/stop and availability.
    • SessionReplayExporter: Subscribe to SessionManager.publisher() to refresh session info; cancel on deinit.
    • SessionReplayService: Minor wiring cleanup for exporter initialization.
  • Common:
    • Broadcaster: Add deinit to silently finish all continuations; simplify stream setup and termination handling.
  • Tests:
    • Update memory tests to use Combine publishers instead of AsyncStream and ensure deallocation/cancellation.

Written by Cursor Bugbot for commit ca1a811. This will update automatically on new commits. Configure here.

* main:
  chore: Objective-c recordLog  (#94)
  chore(main): release 0.12.1 (#91)
  fix: Remove double image workaround for RRWeb (#92)
  fix: hold broadcaster until deinit finishes (#90)

# Conflicts:
#	Tests/ObservabilityTests/Session/AppLifecycleManagerMemoryTests.swift
@mario-launchdarkly
Copy link
Copy Markdown
Contributor

Approved. Tackle the cursor's comments please

* main:
  chore(main): release 0.13.0 (#96)
  feat: Identify support (OBS + SR) (#93)

# Conflicts:
#	TestApp/Sources/AppDelegate.swift
@abelonogov-ld abelonogov-ld enabled auto-merge (squash) December 12, 2025 17:51
let notifyStatus = EventNotifyStatus(id: typeId, status: status)
await broadcaster.send(notifyStatus)
subject.send(notifyStatus)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: EventQueue subject.send called from concurrent Tasks

The notify() method creates a Task that calls subject.send() on a PassthroughSubject. Since EventQueue is an actor, multiple notify() calls create multiple Tasks that can execute concurrently on different threads. The previous implementation used await broadcaster.send() which was actor-isolated and serialized calls. Now PassthroughSubject.send() may be called concurrently from multiple threads, which is not guaranteed to be thread-safe.

Fix in Cursor Fix in Web

@abelonogov-ld abelonogov-ld merged commit cb4c21d into main Dec 12, 2025
5 checks passed
@abelonogov-ld abelonogov-ld deleted the andrey/app-lify-cycle2 branch December 12, 2025 17:55
abelonogov-ld pushed a commit that referenced this pull request Dec 12, 2025
🤖 I have created a release *beep* *boop*
---


##
[0.13.1](0.13.0...0.13.1)
(2025-12-12)


### Bug Fixes

* Rewrite AppLifeCycleManager onto Combine
([#95](#95))
([cb4c21d](cb4c21d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Bump to 0.13.1, updating changelog with bug fix (AppLifeCycleManager
rewritten onto Combine) and syncing podspecs and sdkVersion.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bda38d7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
abelonogov-ld added a commit that referenced this pull request Jan 12, 2026
* main: (38 commits)
  chore(main): release 0.15.2 (#113)
  fix: make unlock await aware (#111)
  Fix SwiftUI hits stealing attempt 2 (#112)
  chore(main): release 0.15.1 (#110)
  fix: ldMask interfere with hit view testing (#108)
  chore(main): release 0.15.0 (#106)
  feat: Deduplicate images before buffering (#107)
  feat: Gzip compression of graphql request (#105)
  chore(main): release 0.14.0 (#103)
  feat: Flush buffers on going to app switcher (#104)
  fix: UIDevice.current.orientation.isLandscape not main thread access (#102)
  feat: Limit accumulating canvas buffer (#101)
  chore: remove disableErrorTracking option (#99)
  chore: remove unused options in observability plugin (#98)
  chore(main): release 0.13.1 (#97)
  fix: Rewrite AppLifeCycleManager onto Combine (#95)
  chore(main): release 0.13.0 (#96)
  feat: Identify support (OBS + SR) (#93)
  chore: Objective-c recordLog  (#94)
  chore(main): release 0.12.1 (#91)
  ...

# Conflicts:
#	Package.swift
#	Sources/LaunchDarklyObservability/Plugin/ObservabilityHook.swift
#	Sources/LaunchDarklyObservability/UIInteractions/TouchIntepreter.swift
#	Sources/Observability/Client/ObservabilityClientFactory.swift
#	Sources/OpenTelemetry/Instrumentation/URLSession/URLSessionLogger.swift
#	TestApp/Sources/AppDelegate.swift
#	TestApp/Sources/MainMenuView.swift
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.

2 participants