Skip to content

feat: adapt Websocket for consumable notifications - WPB-17225 #2918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 48 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
2ee88e2
chore: add new developer flag
netbe Apr 16, 2025
60fb341
feat: register new capability
netbe Apr 16, 2025
fb0986f
chore: save new capability
netbe Apr 16, 2025
c457e64
chore: prepare next ticket
netbe Apr 16, 2025
26bc4e7
format code and add information
netbe Apr 16, 2025
fa322db
fix capabilities new sync
netbe Apr 17, 2025
32f39b0
format code
netbe Apr 17, 2025
b1752a8
fix compile issue
netbe Apr 17, 2025
f22b3d5
Merge branch 'develop' into feat/update-capabilities-WPB-17092
netbe Apr 17, 2025
6062091
cleanup
netbe Apr 17, 2025
c9683cc
wip
netbe Apr 16, 2025
d1bd1ba
wip
netbe Apr 17, 2025
2bd37ab
remove dead code
netbe Apr 17, 2025
461a79e
disable extra info in console's logs
netbe Apr 17, 2025
7e5fc5e
format code
netbe Apr 17, 2025
219d2b3
wip
netbe Apr 17, 2025
11295e2
Merge branch 'develop' into feat/adopt-websocket-WPB-17225
netbe Apr 29, 2025
a2b17f9
fix
netbe Apr 30, 2025
1f8d192
Throw error on missing-notifications event
netbe Apr 30, 2025
67a8bf8
add tests
netbe Apr 30, 2025
e795b9c
wip
netbe May 2, 2025
5a033ef
format
netbe May 2, 2025
36a56d6
Merge branch 'develop' into feat/adopt-websocket-WPB-17225
netbe May 5, 2025
24784d9
wip
netbe May 5, 2025
325ac91
write test
netbe May 5, 2025
ec994f9
skips notifications/last
netbe May 6, 2025
0e032cd
revert bella
netbe May 6, 2025
d6964a0
fix notificationsMissed event
netbe May 6, 2025
967dca2
separate the two protocols
netbe May 6, 2025
510f2c1
try uptodate trigger
netbe May 6, 2025
e59bdba
wip
netbe May 6, 2025
0ad30ab
avoid to open websocket is v2
netbe May 6, 2025
fbb3545
try liveSyncProtocol
netbe May 6, 2025
6459b31
Merge branch 'develop' into feat/adopt-websocket-WPB-17225
netbe May 7, 2025
76a1056
test
netbe May 7, 2025
b02fdc1
Merge remote-tracking branch 'origin/develop' into feat/adopt-websock…
netbe May 12, 2025
1d2d862
make some changes
netbe May 12, 2025
d9fc81a
merge develop
netbe May 12, 2025
4736d9f
add log info
netbe May 12, 2025
0415b73
add log for networkService
netbe May 12, 2025
095fa9f
add more info log
netbe May 12, 2025
477ae3f
debug sending message
netbe May 12, 2025
d31cb47
wip
netbe May 12, 2025
683cb9a
fix
netbe May 13, 2025
2d06761
Merge remote-tracking branch 'origin/develop' into feat/adopt-websock…
netbe May 13, 2025
e9344fe
wip
netbe May 14, 2025
c621d53
Merge remote-tracking branch 'origin/develop' into feat/adopt-websock…
netbe May 14, 2025
99842aa
wip
netbe May 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

// sourcery: AutoMockable
/// An API access object for endpoints concerning the push channel.
public protocol NewPushChannelAPI {

/// Create a new push channel.
///
/// - Parameter clientID: The id of the self client.
/// - Returns: A push channel.

func createPushChannel(clientID: String) async throws -> AnyNewPushChannel

}

// Workaround for automockable compiler error.
public typealias AnyNewPushChannel = any NewPushChannelProtocol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
import Foundation

public struct NewPushChannelAPIBuilder {

private let pushChannelService: PushChannelService

/// Create a new builder.
///
/// - Parameter pushChannelService: A push channel service to execute requests.
///
public init(pushChannelService: PushChannelService) {
self.pushChannelService = pushChannelService
}

/// Make a `PushChannelAPI`.
///
/// - Returns: A `PushChannelAPI`.

public func makeAPI(for apiVersion: APIVersion) -> any NewPushChannelAPI {
NewPushChannelAPIImpl(pushChannelService: pushChannelService, apiVersion: apiVersion)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//


final class NewPushChannelAPIImpl: NewPushChannelAPI, VersionedAPI {

let pushChannelService: any PushChannelServiceProtocol
let apiVersion: APIVersion

init(pushChannelService: any PushChannelServiceProtocol, apiVersion: APIVersion) {
self.pushChannelService = pushChannelService
self.apiVersion = apiVersion
}

func createPushChannel(clientID: String) async throws -> any NewPushChannelProtocol {
let path = "\(pathPrefix)/events"

let request = try URLRequestBuilder(path: path)
.withMethod(.get)
.withQueryItem(name: "client", value: clientID)
.build()

return try await pushChannelService.createNewPushChannel(request)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public struct PushChannelAPIBuilder {
/// Create a new builder.
///
/// - Parameter pushChannelService: A push channel service to execute requests.

///
public init(pushChannelService: PushChannelService) {
self.pushChannelService = pushChannelService
}
Expand All @@ -36,7 +36,7 @@ public struct PushChannelAPIBuilder {
///
/// - Returns: A `PushChannelAPI`.

public func makeAPI() -> any PushChannelAPI {
public func makeAPI(for apiVersion: APIVersion) -> any PushChannelAPI {
PushChannelAPIImpl(pushChannelService: pushChannelService)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import Foundation

class PushChannelAPIImpl: PushChannelAPI {
final class PushChannelAPIImpl: PushChannelAPI {

let pushChannelService: any PushChannelServiceProtocol

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public struct UpdateEventEnvelopeV0: Decodable, ToAPIModelConvertible {
UpdateEventEnvelope(
id: id,
events: (payload ?? []).map(\.updateEvent),
isTransient: transient ?? false
isTransient: transient ?? false,
deliveryTag: nil
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

for old enveloppes there is no acknowledgement so no deliveryTag needed

)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

import Foundation

struct UpdateEventEnvelopeV8: Decodable {
enum CodingKeys: String, CodingKey {
case id
case payload
}

let id: UUID
let payload: [UpdateEventDecodingProxy]
}
16 changes: 0 additions & 16 deletions WireAPI/Sources/WireAPI/Assembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,6 @@ public final class Assembly {
return service
}()

private lazy var pushChannelService: some PushChannelServiceProtocol = PushChannelService(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

unused code

networkService: pushChannelNetworkService,
authenticationManager: authenticationManager
)

private lazy var pushChannelNetworkService: NetworkService = {
let service = NetworkService(
baseURL: backendEnvironment.webSocketURL,
serverTrustValidator: serverTrustValidator
)
let config = urlSessionConfigurationFactory.makeWebSocketSessionConfiguration()
let session = URLSession(configuration: config, delegate: service, delegateQueue: nil)
service.configure(with: session)
return service
}()

public lazy var authenticationManager: some AuthenticationManagerProtocol = AuthenticationManager(
clientID: clientID,
cookieStorage: cookieStorage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public struct UpdateEventEnvelope: Equatable, Sendable {

public let isTransient: Bool

public let deliveryTag: UInt64?

/// Create a new `UpdateEventEnvelope`.
///
/// - Parameters:
Expand All @@ -47,11 +49,13 @@ public struct UpdateEventEnvelope: Equatable, Sendable {
public init(
id: UUID,
events: [UpdateEvent],
isTransient: Bool
isTransient: Bool,
deliveryTag: UInt64? = nil
) {
self.id = id
self.events = events
self.isTransient = isTransient
self.deliveryTag = deliveryTag
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//

import Foundation
import WireLogging

// sourcery: AutoMockable
public protocol NetworkServiceProtocol {
Expand Down Expand Up @@ -102,7 +103,7 @@ extension NetworkService: URLSessionWebSocketDelegate {
webSocketTask: URLSessionWebSocketTask,
didOpenWithProtocol protocol: String?
) {
print("web socket task did open")
WireLogger.network.debug("web socket task did open")
}

public func urlSession(
Expand All @@ -128,9 +129,9 @@ extension NetworkService: URLSessionTaskDelegate {
) {
// NOTE: This method is not called when when using async/await APIs.
if let error {
print("task did complete with error: \(error)")
WireLogger.network.error("task did complete with error: \(error)")
} else {
print("task did complete")
WireLogger.network.debug("task did complete")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
import Foundation

enum AcknowledgmentType: String, Encodable {
case fullSync = "ack_full_sync"
case ack
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
import Foundation

struct EventAcknowledgmentNotification: Encodable {

struct AcknowledgmentData: Encodable {
enum CodingKeys: String, CodingKey {
case deliveryTag = "delivery_tag"
case multiple
}

var deliveryTag: UInt64
var multiple: Bool
}

let type: AcknowledgmentType = .ack
var data: AcknowledgmentData

init(deliveryTag: UInt64, multiple: Bool) {
self.data = .init(deliveryTag: deliveryTag, multiple: multiple)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
import Foundation

struct FullSyncAcknowledgmentNotification: Encodable {
let type: AcknowledgmentType = .fullSync
}
Loading