Avoid creating multiple clients if the NSE is invoked more than once on the same process

This commit is contained in:
Stefan Ceriu 2024-06-19 17:03:05 +03:00 committed by Stefan Ceriu
parent 6655833719
commit f291f10f46

View File

@ -50,6 +50,9 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
private var handler: ((UNNotificationContent) -> Void)? private var handler: ((UNNotificationContent) -> Void)?
private var modifiedContent: UNMutableNotificationContent? private var modifiedContent: UNMutableNotificationContent?
// Used to create one single UserSession across process/instances/runs
private static var userSession: NSEUserSession?
override func didReceive(_ request: UNNotificationRequest, override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory), guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory),
@ -75,6 +78,17 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
MXLog.info("\(tag) Payload came: \(request.content.userInfo)") MXLog.info("\(tag) Payload came: \(request.content.userInfo)")
Task { Task {
if Self.userSession == nil {
// This function might be run concurrently and from different processes
// It's imperative that we create **at most** one UserSession/Client per process
do {
Self.userSession = try await NSEUserSession(credentials: credentials, clientSessionDelegate: keychainController)
} catch {
MXLog.error("NSE run error: \(error)")
return discard(unreadCount: request.unreadCount)
}
}
await run(with: credentials, await run(with: credentials,
roomId: roomId, roomId: roomId,
eventId: eventId, eventId: eventId,
@ -95,11 +109,12 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
unreadCount: Int?) async { unreadCount: Int?) async {
MXLog.info("\(tag) run with roomId: \(roomId), eventId: \(eventId)") MXLog.info("\(tag) run with roomId: \(roomId), eventId: \(eventId)")
do { guard let userSession = Self.userSession else {
// This function might be run concurrently and from different processes, let the SDK handle race conditions MXLog.error("Invalid NSE User Session, discarding.")
// on fetching user sessions return discard(unreadCount: unreadCount)
let userSession = try await NSEUserSession(credentials: credentials, clientSessionDelegate: keychainController) }
do {
guard let itemProxy = await userSession.notificationItemProxy(roomID: roomId, eventID: eventId) else { guard let itemProxy = await userSession.notificationItemProxy(roomID: roomId, eventID: eventId) else {
MXLog.info("\(tag) no notification for the event, discard") MXLog.info("\(tag) no notification for the event, discard")
return discard(unreadCount: unreadCount) return discard(unreadCount: unreadCount)