2022-05-06 04:44:26 +02:00
|
|
|
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
|
|
|
|
import Foundation
|
2022-11-27 22:32:32 +01:00
|
|
|
import Combine
|
2022-05-06 04:44:26 +02:00
|
|
|
import GRDB
|
|
|
|
import SessionSnodeKit
|
2022-06-01 09:41:20 +02:00
|
|
|
import SessionUtilitiesKit
|
2020-11-11 00:58:56 +01:00
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
public final class ClosedGroupPoller: Poller {
|
|
|
|
public static var namespaces: [SnodeAPI.Namespace] = [.legacyClosedGroup]
|
2020-11-11 00:58:56 +01:00
|
|
|
|
2022-05-08 14:01:39 +02:00
|
|
|
// MARK: - Settings
|
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
override var namespaces: [SnodeAPI.Namespace] { ClosedGroupPoller.namespaces }
|
|
|
|
override var maxNodePollCount: UInt { 0 }
|
2022-05-08 14:01:39 +02:00
|
|
|
|
2023-07-10 09:56:58 +02:00
|
|
|
private static let minPollInterval: Double = 3
|
2021-07-30 01:23:56 +02:00
|
|
|
private static let maxPollInterval: Double = 30
|
2020-11-11 00:58:56 +01:00
|
|
|
|
2022-05-08 14:01:39 +02:00
|
|
|
// MARK: - Initialization
|
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
public static let shared: ClosedGroupPoller = ClosedGroupPoller()
|
2021-05-12 02:33:29 +02:00
|
|
|
|
2022-05-08 14:01:39 +02:00
|
|
|
// MARK: - Public API
|
|
|
|
|
2023-08-01 06:27:41 +02:00
|
|
|
public func start(using dependencies: Dependencies = Dependencies()) {
|
2022-05-09 06:45:14 +02:00
|
|
|
// Fetch all closed groups (excluding any don't contain the current user as a
|
|
|
|
// GroupMemeber as the user is no longer a member of those)
|
2023-08-01 06:27:41 +02:00
|
|
|
dependencies.storage
|
2022-05-08 14:01:39 +02:00
|
|
|
.read { db in
|
|
|
|
try ClosedGroup
|
|
|
|
.select(.threadId)
|
2022-05-09 06:45:14 +02:00
|
|
|
.joining(
|
|
|
|
required: ClosedGroup.members
|
2023-08-01 06:27:41 +02:00
|
|
|
.filter(GroupMember.Columns.profileId == getUserHexEncodedPublicKey(db, using: dependencies))
|
2022-05-09 06:45:14 +02:00
|
|
|
)
|
2022-05-08 14:01:39 +02:00
|
|
|
.asRequest(of: String.self)
|
|
|
|
.fetchAll(db)
|
|
|
|
}
|
|
|
|
.defaulting(to: [])
|
2022-11-27 22:32:32 +01:00
|
|
|
.forEach { [weak self] publicKey in
|
2023-08-01 06:27:41 +02:00
|
|
|
self?.startIfNeeded(for: publicKey, using: dependencies)
|
2022-05-08 14:01:39 +02:00
|
|
|
}
|
2020-11-11 00:58:56 +01:00
|
|
|
}
|
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
// MARK: - Abstract Methods
|
2022-05-08 14:01:39 +02:00
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
override func pollerName(for publicKey: String) -> String {
|
|
|
|
return "closed group with public key: \(publicKey)"
|
2021-05-12 02:33:29 +02:00
|
|
|
}
|
|
|
|
|
2023-08-01 06:27:41 +02:00
|
|
|
override func nextPollDelay(for publicKey: String, using dependencies: Dependencies) -> TimeInterval {
|
2022-11-27 22:32:32 +01:00
|
|
|
// Get the received date of the last message in the thread. If we don't have
|
|
|
|
// any messages yet, pick some reasonable fake time interval to use instead
|
2022-07-01 05:08:45 +02:00
|
|
|
let lastMessageDate: Date = Storage.shared
|
2022-05-08 14:01:39 +02:00
|
|
|
.read { db in
|
2022-11-27 22:32:32 +01:00
|
|
|
try Interaction
|
|
|
|
.filter(Interaction.Columns.threadId == publicKey)
|
2022-05-08 14:01:39 +02:00
|
|
|
.select(.receivedAtTimestampMs)
|
|
|
|
.order(Interaction.Columns.timestampMs.desc)
|
|
|
|
.asRequest(of: Int64.self)
|
|
|
|
.fetchOne(db)
|
|
|
|
}
|
|
|
|
.map { receivedAtTimestampMs -> Date? in
|
|
|
|
guard receivedAtTimestampMs > 0 else { return nil }
|
|
|
|
|
|
|
|
return Date(timeIntervalSince1970: (TimeInterval(receivedAtTimestampMs) / 1000))
|
|
|
|
}
|
|
|
|
.defaulting(to: Date().addingTimeInterval(-5 * 60))
|
2022-06-08 06:29:51 +02:00
|
|
|
|
2023-08-01 06:27:41 +02:00
|
|
|
let timeSinceLastMessage: TimeInterval = dependencies.dateNow.timeIntervalSince(lastMessageDate)
|
2022-05-08 14:01:39 +02:00
|
|
|
let minPollInterval: Double = ClosedGroupPoller.minPollInterval
|
|
|
|
let limit: Double = (12 * 60 * 60)
|
2022-11-27 22:32:32 +01:00
|
|
|
let a: TimeInterval = ((ClosedGroupPoller.maxPollInterval - minPollInterval) / limit)
|
|
|
|
let nextPollInterval: TimeInterval = a * min(timeSinceLastMessage, limit) + minPollInterval
|
|
|
|
SNLog("Next poll interval for closed group with public key: \(publicKey) is \(nextPollInterval) s.")
|
2022-06-08 06:29:51 +02:00
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
return nextPollInterval
|
2021-05-12 02:33:29 +02:00
|
|
|
}
|
2022-08-04 10:09:03 +02:00
|
|
|
|
2023-08-01 06:27:41 +02:00
|
|
|
override func handlePollError(_ error: Error, for publicKey: String, using dependencies: Dependencies) -> Bool {
|
2022-11-27 22:32:32 +01:00
|
|
|
SNLog("Polling failed for closed group with public key: \(publicKey) due to error: \(error).")
|
2023-07-10 09:56:58 +02:00
|
|
|
return true
|
2020-11-11 00:58:56 +01:00
|
|
|
}
|
|
|
|
}
|