Skip to content

Commit

Permalink
Performance follow ups (#451)
Browse files Browse the repository at this point in the history
* performance follow ups

* write a test
  • Loading branch information
nplasterer authored Dec 20, 2024
1 parent 0127d21 commit cfd45dd
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
.package(url: "https://github.com/bufbuild/connect-swift", exact: "1.0.0"),
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.4.3"),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", exact: "1.8.3"),
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.13")
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.14")
],
targets: [
.target(
Expand Down
76 changes: 39 additions & 37 deletions Sources/XMTPiOS/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,27 @@ public struct ClientOptions {
}
}

actor ApiClientCache {
private var apiClientCache: [String: XmtpApiClient] = [:]

func getClient(forKey key: String) -> XmtpApiClient? {
return apiClientCache[key]
}

func setClient(_ client: XmtpApiClient, forKey key: String) {
apiClientCache[key] = client
}
}

public final class Client {
public let address: String
public let inboxID: String
public let libXMTPVersion: String = getVersionInfo()
public let dbPath: String
public let installationID: String
public let environment: XMTPEnvironment
public let apiClient: XmtpApiClient
private let ffiClient: LibXMTP.FfiXmtpClient
private static let apiCache = ApiClientCache()

public lazy var conversations: Conversations = .init(
client: self, ffiConversations: ffiClient.conversations())
Expand All @@ -112,12 +124,11 @@ public final class Client {
inboxId: String,
apiClient: XmtpApiClient? = nil
) async throws -> Client {
let (libxmtpClient, dbPath, apiClient) = try await initFFiClient(
let (libxmtpClient, dbPath) = try await initFFiClient(
accountAddress: accountAddress.lowercased(),
options: options,
signingKey: signingKey,
inboxId: inboxId,
apiClient: apiClient
inboxId: inboxId
)

let client = try Client(
Expand All @@ -126,8 +137,7 @@ public final class Client {
dbPath: dbPath,
installationID: libxmtpClient.installationId().toHex,
inboxID: libxmtpClient.inboxId(),
environment: options.api.env,
apiClient: apiClient
environment: options.api.env
)

// Register codecs
Expand All @@ -139,8 +149,7 @@ public final class Client {
}

public static func create(
account: SigningKey, options: ClientOptions,
apiClient: XmtpApiClient? = nil
account: SigningKey, options: ClientOptions
)
async throws -> Client
{
Expand All @@ -152,14 +161,12 @@ public final class Client {
accountAddress: accountAddress,
options: options,
signingKey: account,
inboxId: inboxId,
apiClient: apiClient
inboxId: inboxId
)
}

public static func build(
address: String, options: ClientOptions, inboxId: String? = nil,
apiClient: XmtpApiClient? = nil
address: String, options: ClientOptions, inboxId: String? = nil
)
async throws -> Client
{
Expand All @@ -176,18 +183,16 @@ public final class Client {
accountAddress: accountAddress,
options: options,
signingKey: nil,
inboxId: resolvedInboxId,
apiClient: apiClient
inboxId: resolvedInboxId
)
}

private static func initFFiClient(
accountAddress: String,
options: ClientOptions,
signingKey: SigningKey?,
inboxId: String,
apiClient: XmtpApiClient? = nil
) async throws -> (FfiXmtpClient, String, XmtpApiClient) {
inboxId: String
) async throws -> (FfiXmtpClient, String) {
let address = accountAddress.lowercased()

let mlsDbDirectory = options.dbDirectory
Expand All @@ -214,15 +219,8 @@ public final class Client {
let alias = "xmtp-\(options.api.env.rawValue)-\(inboxId).db3"
let dbURL = directoryURL.appendingPathComponent(alias).path

let xmtpApiClient: XmtpApiClient
if let existingApiClient = apiClient {
xmtpApiClient = existingApiClient
} else {
xmtpApiClient = try await connectToApiBackend(api: options.api)
}

let ffiClient = try await LibXMTP.createClient(
api: xmtpApiClient,
api: connectToApiBackend(api: options.api),
db: dbURL,
encryptionKey: options.dbEncryptionKey,
inboxId: inboxId,
Expand Down Expand Up @@ -252,7 +250,7 @@ public final class Client {
}
}

return (ffiClient, dbURL, xmtpApiClient)
return (ffiClient, dbURL)
}

private static func handleSignature(
Expand Down Expand Up @@ -282,12 +280,19 @@ public final class Client {
}
}

public static func connectToApiBackend(
api: ClientOptions.Api
) async throws -> XmtpApiClient {
return try await connectToBackend(
host: api.env.url,
isSecure: api.env.isSecure == true)
public static func connectToApiBackend(api: ClientOptions.Api) async throws
-> XmtpApiClient
{
let cacheKey = api.env.url

if let cachedClient = await apiCache.getClient(forKey: cacheKey) {
return cachedClient
}

let apiClient = try await connectToBackend(
host: api.env.url, isSecure: api.isSecure)
await apiCache.setClient(apiClient, forKey: cacheKey)
return apiClient
}

public static func getOrCreateInboxId(
Expand All @@ -297,8 +302,7 @@ public final class Client {
do {
inboxId =
try await getInboxIdForAddress(
host: api.env.url,
isSecure: api.env.isSecure == true,
api: connectToApiBackend(api: api),
accountAddress: address.lowercased()
)
?? generateInboxId(
Expand Down Expand Up @@ -344,16 +348,14 @@ public final class Client {

init(
address: String, ffiClient: LibXMTP.FfiXmtpClient, dbPath: String,
installationID: String, inboxID: String, environment: XMTPEnvironment,
apiClient: XmtpApiClient
installationID: String, inboxID: String, environment: XMTPEnvironment
) throws {
self.address = address
self.ffiClient = ffiClient
self.dbPath = dbPath
self.installationID = installationID
self.inboxID = inboxID
self.environment = environment
self.apiClient = apiClient
}

public func addAccount(newAccount: SigningKey)
Expand Down
25 changes: 6 additions & 19 deletions Tests/XMTPTests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -532,19 +532,18 @@ class ClientTests: XCTestCase {
print("PERF: Built a client with inboxId in \(time3)s")

// Measure time to build a client with an inboxId and apiClient
try await Client.connectToApiBackend(api: ClientOptions.Api(env: .dev, isSecure: true))
let start4 = Date()
let buildClient3 = try await Client.build(
address: fakeWallet.address,
try await Client.create(
account: fakeWallet,
options: ClientOptions(
api: ClientOptions.Api(env: .dev, isSecure: true),
dbEncryptionKey: key
),
inboxId: client.inboxID,
apiClient: client.apiClient
)
)
let end4 = Date()
let time4 = end4.timeIntervalSince(start4)
print("PERF: Built a client with inboxId and apiClient in \(time4)s")
print("PERF: Create a client with prebuild in \(time4)s")

// Assert performance comparisons
XCTAssertTrue(
Expand All @@ -560,15 +559,7 @@ class ClientTests: XCTestCase {
)
XCTAssertTrue(
time4 < time1,
"Building a client with apiClient should be faster than creating one."
)
XCTAssertTrue(
time4 < time2,
"Building a client with apiClient should be faster than building one."
)
XCTAssertTrue(
time4 < time2,
"Building a client with apiClient should be faster than building one with inboxId."
"Creating a client with apiClient should be faster than creating one without."
)

// Assert that inbox IDs match
Expand All @@ -580,10 +571,6 @@ class ClientTests: XCTestCase {
client.inboxID, buildClient2.inboxID,
"Inbox ID of the created client and second built client should match."
)
XCTAssertEqual(
client.inboxID, buildClient3.inboxID,
"Inbox ID of the created client and second built client should match."
)
}

}
4 changes: 2 additions & 2 deletions XMTP.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "XMTP"
spec.version = "3.0.19"
spec.version = "3.0.20"

spec.summary = "XMTP SDK Cocoapod"

Expand All @@ -23,7 +23,7 @@ Pod::Spec.new do |spec|

spec.dependency 'CSecp256k1', '~> 0.2'
spec.dependency "Connect-Swift", "= 1.0.0"
spec.dependency 'LibXMTP', '= 3.0.13'
spec.dependency 'LibXMTP', '= 3.0.14'
spec.dependency 'CryptoSwift', '= 1.8.3'
spec.dependency 'SQLCipher', '= 4.5.7'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/xmtp/libxmtp-swift.git",
"state" : {
"revision" : "203fd6d67bb72e3114b273ce9bbddd6fc747d583",
"version" : "3.0.13"
"revision" : "9cf94acdea7d03008b1f130a9848c38ee6b711de",
"version" : "3.0.14"
}
},
{
Expand Down

0 comments on commit cfd45dd

Please sign in to comment.