Fixed an endless loading state when clearing data with no network

pull/1018/head
Morgan Pretty 7 months ago
parent 3366408187
commit a02bc55445

@ -1 +1 @@
Subproject commit ac34aa26aa78066aeaa443fe30f384821d4ae36e
Subproject commit c3aa3b99e05d7e7568cdd1dc2e0f1200e3ec01f1

@ -179,7 +179,17 @@ final class NukeDataModal: Modal {
.distinct()
.asRequest(of: String.self)
.fetchSet(db)
.map { ($0, try OpenGroupAPI.preparedClearInbox(db, on: $0, using: dependencies))}
.map { server in
(
server,
try OpenGroupAPI.preparedClearInbox(
db,
on: server,
requestAndPathBuildTimeout: Network.defaultTimeout,
using: dependencies
)
)
}
}
.defaulting(to: [])
.compactMap { server, preparedRequest in
@ -193,7 +203,10 @@ final class NukeDataModal: Modal {
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
.flatMap { results in
SnodeAPI
.deleteAllMessages(namespace: .all)
.deleteAllMessages(
namespace: .all,
requestAndPathBuildTimeout: Network.defaultTimeout
)
.map { results.reduce($0) { result, next in result.updated(with: next) } }
.eraseToAnyPublisher()
}

@ -975,6 +975,8 @@ public enum OpenGroupAPI {
public static func preparedClearInbox(
_ db: Database,
on server: String,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies
) throws -> Network.PreparedRequest<DeleteInboxResponse> {
return try OpenGroupAPI
@ -986,6 +988,8 @@ public enum OpenGroupAPI {
endpoint: .inbox
),
responseType: DeleteInboxResponse.self,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
.signed(db, with: OpenGroupAPI.signRequest, using: dependencies)
@ -1463,14 +1467,16 @@ public enum OpenGroupAPI {
private static func prepareRequest<T: Encodable, R: Decodable>(
request: Request<T, Endpoint>,
responseType: R.Type,
timeout: TimeInterval = Network.defaultTimeout,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies
) throws -> Network.PreparedRequest<R> {
return Network.PreparedRequest(
request: request,
urlRequest: try request.generateUrlRequest(using: dependencies),
responseType: responseType,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
)
}
}

@ -496,7 +496,8 @@ public enum PushNotificationAPI {
request: Request<T, Endpoint>,
responseType: R.Type,
retryCount: Int = 0,
timeout: TimeInterval = Network.defaultTimeout,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies
) throws -> Network.PreparedRequest<R> {
return Network.PreparedRequest<R>(
@ -504,7 +505,8 @@ public enum PushNotificationAPI {
urlRequest: try request.generateUrlRequest(using: dependencies),
responseType: responseType,
retryCount: retryCount,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
)
}
}

@ -230,7 +230,8 @@ public extension LibSession {
to destination: Network.Destination,
body: T?,
swarmPublicKey: String?,
timeout: TimeInterval,
requestTimeout: TimeInterval,
requestAndPathBuildTimeout: TimeInterval?,
using dependencies: Dependencies
) -> AnyPublisher<(ResponseInfoType, Data?), Error> {
typealias Output = (success: Bool, timeout: Bool, statusCode: Int, data: Data?)
@ -269,7 +270,8 @@ public extension LibSession {
cPayloadBytes,
cPayloadBytes.count,
cSwarmPublicKey,
Int64(floor(timeout * 1000)),
Int64(floor(requestTimeout * 1000)),
Int64(floor((requestAndPathBuildTimeout ?? 0) * 1000)),
{ success, timeout, statusCode, dataPtr, dataLen, ctx in
let data: Data? = dataPtr.map { Data(bytes: $0, count: dataLen) }
CallbackWrapper<Output>.run(ctx, (success, timeout, Int(statusCode), data))
@ -283,7 +285,8 @@ public extension LibSession {
try wrapper.cServerDestination(destination),
cPayloadBytes,
cPayloadBytes.count,
Int64(floor(timeout * 1000)),
Int64(floor(requestTimeout * 1000)),
Int64(floor((requestAndPathBuildTimeout ?? 0) * 1000)),
{ success, timeout, statusCode, dataPtr, dataLen, ctx in
let data: Data? = dataPtr.map { Data(bytes: $0, count: dataLen) }
CallbackWrapper<Output>.run(ctx, (success, timeout, Int(statusCode), data))
@ -319,6 +322,7 @@ public extension LibSession {
data.count,
fileName?.cString(using: .utf8),
Int64(floor(Network.fileUploadTimeout * 1000)),
0,
{ success, timeout, statusCode, dataPtr, dataLen, ctx in
let data: Data? = dataPtr.map { Data(bytes: $0, count: dataLen) }
CallbackWrapper<Output>.run(ctx, (success, timeout, Int(statusCode), data))
@ -350,6 +354,7 @@ public extension LibSession {
network,
try wrapper.cServerDestination(server),
Int64(floor(Network.fileDownloadTimeout * 1000)),
0,
{ success, timeout, statusCode, dataPtr, dataLen, ctx in
let data: Data? = dataPtr.map { Data(bytes: $0, count: dataLen) }
CallbackWrapper<Output>.run(ctx, (success, timeout, Int(statusCode), data))
@ -387,6 +392,7 @@ public extension LibSession {
CLIENT_PLATFORM_IOS,
&cEd25519SecretKey,
Int64(floor(Network.fileDownloadTimeout * 1000)),
0,
{ success, timeout, statusCode, dataPtr, dataLen, ctx in
let data: Data? = dataPtr.map { Data(bytes: $0, count: dataLen) }
CallbackWrapper<Output>.run(ctx, (success, timeout, Int(statusCode), data))

@ -11,20 +11,22 @@ public extension Network.RequestType {
_ payload: Data,
to snode: LibSession.Snode,
swarmPublicKey: String?,
timeout: TimeInterval = Network.defaultTimeout
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil
) -> Network.RequestType<Data?> {
return Network.RequestType(
id: "onionRequest",
url: "quic://\(snode.address)",
method: "POST",
body: payload,
args: [payload, snode, swarmPublicKey, timeout]
args: [payload, snode, swarmPublicKey, requestTimeout, requestAndPathBuildTimeout]
) { dependencies in
LibSession.sendOnionRequest(
to: Network.Destination.snode(snode),
body: payload,
swarmPublicKey: swarmPublicKey,
timeout: timeout,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
}
@ -34,7 +36,8 @@ public extension Network.RequestType {
_ request: URLRequest,
to server: String,
with x25519PublicKey: String,
timeout: TimeInterval = Network.defaultTimeout
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil
) -> Network.RequestType<Data?> {
return Network.RequestType(
id: "onionRequest",
@ -42,9 +45,9 @@ public extension Network.RequestType {
method: request.httpMethod,
headers: request.allHTTPHeaderFields,
body: request.httpBody,
args: [request, server, x25519PublicKey, timeout]
args: [request, server, x25519PublicKey, requestTimeout, requestAndPathBuildTimeout]
) { dependencies in
guard let url = request.url, let host = request.url?.host else {
guard let url = request.url else {
return Fail(error: NetworkError.invalidURL).eraseToAnyPublisher()
}
@ -57,7 +60,8 @@ public extension Network.RequestType {
),
body: request.httpBody,
swarmPublicKey: nil,
timeout: timeout,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
}

@ -32,7 +32,8 @@ public extension Network.PreparedRequest {
request,
to: serverTarget.server,
with: serverTarget.x25519PublicKey,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
),
using: dependencies
)
@ -46,7 +47,8 @@ public extension Network.PreparedRequest {
payload,
to: snodeTarget.snode,
swarmPublicKey: snodeTarget.swarmPublicKey,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
),
using: dependencies
)
@ -62,7 +64,8 @@ public extension Network.PreparedRequest {
payload,
to: snode,
swarmPublicKey: randomTarget.swarmPublicKey,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
),
using: dependencies
)
@ -74,7 +77,12 @@ public extension Network.PreparedRequest {
return LibSession.getSwarm(swarmPublicKey: randomTarget.swarmPublicKey)
.tryFlatMapWithRandomSnode(retry: randomTarget.retryCount, using: dependencies) { snode in
SnodeAPI
.getNetworkTime(from: snode, using: dependencies)
.getNetworkTime(
from: snode,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
.tryFlatMap { timestampMs in
guard
let updatedRequest: URLRequest = try? randomTarget
@ -88,7 +96,8 @@ public extension Network.PreparedRequest {
payload,
to: snode,
swarmPublicKey: randomTarget.swarmPublicKey,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
),
using: dependencies
)

@ -740,7 +740,7 @@ public final class SnodeAPI {
)
.send(using: dependencies)
.tryMap { _, response -> Void in
try response.validResultMap(
_ = try response.validResultMap(
swarmPublicKey: getUserHexEncodedPublicKey(),
validationData: subkeyToRevoke,
using: dependencies
@ -860,6 +860,8 @@ public final class SnodeAPI {
/// Clears all the user's data from their swarm. Returns a dictionary of snode public key to deletion confirmation.
public static func deleteAllMessages(
namespace: SnodeAPI.Namespace,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies = Dependencies()
) -> AnyPublisher<[String: Bool], Error> {
guard let userED25519KeyPair = Identity.fetchUserEd25519KeyPair() else {
@ -882,9 +884,12 @@ public final class SnodeAPI {
timestampMs: UInt64(SnodeAPI.currentOffsetTimestampMs()),
ed25519PublicKey: userED25519KeyPair.publicKey,
ed25519SecretKey: userED25519KeyPair.secretKey
)
),
retryCount: 0 // Don't auto retry this request (user can manually retry on failure)
),
responseType: DeleteAllMessagesResponse.self,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
.send(using: dependencies)
@ -931,7 +936,8 @@ public final class SnodeAPI {
timestampMs: UInt64(SnodeAPI.currentOffsetTimestampMs()),
ed25519PublicKey: userED25519KeyPair.publicKey,
ed25519SecretKey: userED25519KeyPair.secretKey
)
),
retryCount: 0 // Don't auto retry this request (user can manually retry on failure)
),
responseType: DeleteAllBeforeResponse.self,
using: dependencies
@ -953,6 +959,8 @@ public final class SnodeAPI {
public static func getNetworkTime(
from snode: LibSession.Snode,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies
) -> AnyPublisher<UInt64, Error> {
do {
@ -964,6 +972,8 @@ public final class SnodeAPI {
body: [String: String]()
),
responseType: GetNetworkTimestampResponse.self,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
using: dependencies
)
.send(using: dependencies)
@ -987,7 +997,8 @@ public final class SnodeAPI {
responseType: R.Type,
requireAllBatchResponses: Bool = true,
retryCount: Int = 0,
timeout: TimeInterval = Network.defaultTimeout,
requestTimeout: TimeInterval = Network.defaultTimeout,
requestAndPathBuildTimeout: TimeInterval? = nil,
using dependencies: Dependencies
) throws -> Network.PreparedRequest<R> {
return Network.PreparedRequest<R>(
@ -996,7 +1007,8 @@ public final class SnodeAPI {
responseType: responseType,
requireAllBatchResponses: requireAllBatchResponses,
retryCount: retryCount,
timeout: timeout
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout
)
.handleEvents(
receiveOutput: { _, response in
@ -1140,7 +1152,7 @@ private extension Request {
swarmPublicKey: String,
requiresLatestNetworkTime: Bool,
body: B,
retryCount: Int = SnodeAPI.maxRetryCount
retryCount: Int
) where T == SnodeRequest<B>, Endpoint == SnodeAPI.Endpoint, B: Encodable & UpdatableTimestamp {
self = Request(
method: .post,

@ -40,7 +40,7 @@ class SnodeRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)

@ -19,7 +19,8 @@ public extension Network {
public let originalType: Decodable.Type
public let responseType: R.Type
public let retryCount: Int
public let timeout: TimeInterval
public let requestTimeout: TimeInterval
public let requestAndPathBuildTimeout: TimeInterval?
public let cachedResponse: CachedResponse?
fileprivate let responseConverter: ((ResponseInfoType, Any) throws -> R)
public let subscriptionHandler: (() -> Void)?
@ -49,7 +50,8 @@ public extension Network {
responseType: R.Type,
requireAllBatchResponses: Bool = true,
retryCount: Int = 0,
timeout: TimeInterval
requestTimeout: TimeInterval,
requestAndPathBuildTimeout: TimeInterval? = nil
) where R: Decodable {
let batchRequests: [Network.BatchRequest.Child]? = (request.body as? BatchRequestChildRetrievable)?.requests
let batchEndpoints: [E] = (batchRequests?
@ -68,7 +70,8 @@ public extension Network {
self.originalType = R.self
self.responseType = responseType
self.retryCount = retryCount
self.timeout = timeout
self.requestTimeout = requestTimeout
self.requestAndPathBuildTimeout = requestAndPathBuildTimeout
self.cachedResponse = nil
// When we are making a batch request we also want to call though any sub request event
@ -246,7 +249,8 @@ public extension Network {
originalType: U.Type,
responseType: R.Type,
retryCount: Int,
timeout: TimeInterval,
requestTimeout: TimeInterval,
requestAndPathBuildTimeout: TimeInterval?,
cachedResponse: CachedResponse?,
responseConverter: @escaping (ResponseInfoType, Any) throws -> R,
subscriptionHandler: (() -> Void)?,
@ -272,7 +276,8 @@ public extension Network {
self.originalType = originalType
self.responseType = responseType
self.retryCount = retryCount
self.timeout = timeout
self.requestTimeout = requestTimeout
self.requestAndPathBuildTimeout = requestAndPathBuildTimeout
self.cachedResponse = cachedResponse
self.responseConverter = responseConverter
self.subscriptionHandler = subscriptionHandler
@ -420,7 +425,8 @@ public extension Network.PreparedRequest {
originalType: originalType,
responseType: responseType,
retryCount: retryCount,
timeout: timeout,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
cachedResponse: cachedResponse,
responseConverter: responseConverter,
subscriptionHandler: subscriptionHandler,
@ -464,7 +470,8 @@ public extension Network.PreparedRequest {
originalType: originalType,
responseType: O.self,
retryCount: retryCount,
timeout: timeout,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
cachedResponse: cachedResponse.map { data in
(try? responseConverter(data.info, data.convertedData))
.map { convertedData in
@ -573,7 +580,8 @@ public extension Network.PreparedRequest {
originalType: originalType,
responseType: responseType,
retryCount: retryCount,
timeout: timeout,
requestTimeout: requestTimeout,
requestAndPathBuildTimeout: requestAndPathBuildTimeout,
cachedResponse: cachedResponse,
responseConverter: responseConverter,
subscriptionHandler: subscriptionHandler,
@ -610,7 +618,8 @@ public extension Network.PreparedRequest {
originalType: R.self,
responseType: R.self,
retryCount: 0,
timeout: 0,
requestTimeout: 0,
requestAndPathBuildTimeout: nil,
cachedResponse: Network.PreparedRequest<R>.CachedResponse(
info: Network.ResponseInfo(code: 0, headers: [:]),
originalData: cachedResponse,

@ -39,7 +39,7 @@ class BatchRequestSpec: QuickSpec {
request: httpRequest,
urlRequest: try! httpRequest.generateUrlRequest(using: dependencies),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -73,7 +73,7 @@ class BatchRequestSpec: QuickSpec {
request: httpRequest,
urlRequest: try! httpRequest.generateUrlRequest(using: dependencies),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -104,7 +104,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -133,7 +133,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -162,7 +162,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -195,7 +195,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -225,7 +225,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)
@ -255,7 +255,7 @@ class BatchRequestSpec: QuickSpec {
),
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
responseType: NoResponse.self,
timeout: 0
requestTimeout: 0
)
]
)

@ -41,7 +41,7 @@ class PreparedRequestSpec: QuickSpec {
request: request,
urlRequest: try! request.generateUrlRequest(using: dependencies),
responseType: TestType.self,
timeout: 10
requestTimeout: 10
)
expect(preparedRequest.request.url?.absoluteString).to(equal("testServer/endpoint"))
@ -70,7 +70,7 @@ class PreparedRequestSpec: QuickSpec {
request: request,
urlRequest: try! request.generateUrlRequest(using: dependencies),
responseType: TestType.self,
timeout: 10
requestTimeout: 10
)
expect(TestEndpoint.excludedSubRequestHeaders).to(equal([HTTPHeader.testHeader]))

Loading…
Cancel
Save