mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Refactoring
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import Foundation
|
||||
import SwiftSignalKit
|
||||
import MtProtoKit
|
||||
|
||||
import SyncCore
|
||||
|
||||
public enum ProxyServerStatus: Equatable {
|
||||
case checking
|
||||
case notAvailable
|
||||
case available(Double)
|
||||
}
|
||||
|
||||
private final class ProxyServerItemContext {
|
||||
private var disposable: Disposable?
|
||||
var value: ProxyServerStatus = .checking
|
||||
|
||||
init(queue: Queue, context: MTContext, datacenterId: Int, server: ProxyServerSettings, updated: @escaping (ProxyServerStatus) -> Void) {
|
||||
self.disposable = (Signal<ProxyServerStatus, NoError> { subscriber in
|
||||
let disposable = MTProxyConnectivity.pingProxy(with: context, datacenterId: datacenterId, settings: server.mtProxySettings).start(next: { next in
|
||||
if let next = next as? MTProxyConnectivityStatus {
|
||||
if !next.reachable {
|
||||
subscriber.putNext(.notAvailable)
|
||||
} else {
|
||||
subscriber.putNext(.available(next.roundTripTime))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
disposable?.dispose()
|
||||
}
|
||||
} |> runOn(queue)).start(next: { status in
|
||||
updated(status)
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
final class ProxyServersStatusesImpl {
|
||||
private let queue: Queue
|
||||
|
||||
private var contexts: [ProxyServerSettings: ProxyServerItemContext] = [:]
|
||||
private var serversDisposable: Disposable?
|
||||
|
||||
private var currentValues: [ProxyServerSettings: ProxyServerStatus] = [:] {
|
||||
didSet {
|
||||
self.values.set(.single(self.currentValues))
|
||||
}
|
||||
}
|
||||
let values = Promise<[ProxyServerSettings: ProxyServerStatus]>([:])
|
||||
|
||||
init(queue: Queue, network: Network, servers: Signal<[ProxyServerSettings], NoError>) {
|
||||
self.queue = queue
|
||||
|
||||
self.serversDisposable = (servers
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] servers in
|
||||
if let strongSelf = self {
|
||||
let validKeys = Set<ProxyServerSettings>(servers)
|
||||
for key in validKeys {
|
||||
if strongSelf.contexts[key] == nil {
|
||||
let context = ProxyServerItemContext(queue: strongSelf.queue, context: network.context, datacenterId: network.datacenterId, server: key, updated: { value in
|
||||
queue.async {
|
||||
if let strongSelf = self {
|
||||
strongSelf.contexts[key]?.value = value
|
||||
strongSelf.updateValues()
|
||||
}
|
||||
}
|
||||
})
|
||||
strongSelf.contexts[key] = context
|
||||
}
|
||||
}
|
||||
var removeKeys: [ProxyServerSettings] = []
|
||||
for (key, _) in strongSelf.contexts {
|
||||
if !validKeys.contains(key) {
|
||||
removeKeys.append(key)
|
||||
}
|
||||
}
|
||||
for key in removeKeys {
|
||||
let _ = strongSelf.contexts.removeValue(forKey: key)
|
||||
}
|
||||
if !removeKeys.isEmpty {
|
||||
strongSelf.updateValues()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.serversDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func updateValues() {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
var values: [ProxyServerSettings: ProxyServerStatus] = [:]
|
||||
for (key, context) in self.contexts {
|
||||
values[key] = context.value
|
||||
}
|
||||
self.currentValues = values
|
||||
}
|
||||
}
|
||||
|
||||
public final class ProxyServersStatuses {
|
||||
private let impl: QueueLocalObject<ProxyServersStatusesImpl>
|
||||
|
||||
public init(network: Network, servers: Signal<[ProxyServerSettings], NoError>) {
|
||||
let queue = Queue()
|
||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||
return ProxyServersStatusesImpl(queue: queue, network: network, servers: servers)
|
||||
})
|
||||
}
|
||||
|
||||
public func statuses() -> Signal<[ProxyServerSettings: ProxyServerStatus], NoError> {
|
||||
return Signal { subscriber in
|
||||
let disposable = MetaDisposable()
|
||||
self.impl.with { impl in
|
||||
disposable.set(impl.values.get().start(next: { value in
|
||||
subscriber.putNext(value)
|
||||
}))
|
||||
}
|
||||
return ActionDisposable {
|
||||
self.impl.with({ _ in })
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user