Skip to content

Commit

Permalink
Paginate per batched query (#96)
Browse files Browse the repository at this point in the history
* add api client with grpc kotlin

* take a pagination object so you can paginate per request

* add more complex test for it

* fix linter issue
  • Loading branch information
nplasterer authored Jul 18, 2023
1 parent a12829b commit 275714c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.xmtp.android.library.messages.MessageBuilder
import org.xmtp.android.library.messages.MessageHeaderV2Builder
import org.xmtp.android.library.messages.MessageV1Builder
import org.xmtp.android.library.messages.MessageV2Builder
import org.xmtp.android.library.messages.Pagination
import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.SealedInvitationBuilder
Expand Down Expand Up @@ -419,27 +420,48 @@ class ConversationTest {

@Test
fun testListBatchMessages() {
val bobConversation = bobClient.conversations.newConversation(
alice.walletAddress,
context = InvitationV1ContextBuilder.buildFromConversation("hi")
)
val bobConversation = aliceClient.conversations.newConversation(bob.walletAddress)
val steveConversation = aliceClient.conversations.newConversation(fixtures.steve.walletAddress)

val aliceConversation = aliceClient.conversations.newConversation(
bob.walletAddress,
context = InvitationV1ContextBuilder.buildFromConversation("hi")
)
bobConversation.send(text = "hey alice 1")
bobConversation.send(text = "hey alice 2")
bobConversation.send(text = "hey alice 3")
steveConversation.send(text = "hey alice 3")
val messages = aliceClient.conversations.listBatchMessages(
listOf(
aliceConversation.topic,
bobConversation.topic
Pair(steveConversation.topic, null),
Pair(bobConversation.topic, null)
)
)
assertEquals(3, messages.size)
}

@Test
fun testListBatchMessagesWithPagination() {
val bobConversation = aliceClient.conversations.newConversation(bob.walletAddress)
val steveConversation =
aliceClient.conversations.newConversation(fixtures.steve.walletAddress)

bobConversation.send(text = "hey alice 1 bob")
steveConversation.send(text = "hey alice 1 steve")

Thread.sleep(100)
val date = Date()

bobConversation.send(text = "hey alice 2 bob")
bobConversation.send(text = "hey alice 3 bob")
steveConversation.send(text = "hey alice 2 steve")
steveConversation.send(text = "hey alice 3 steve")

val messages = aliceClient.conversations.listBatchMessages(
listOf(
Pair(steveConversation.topic, Pagination(after = date)),
Pair(bobConversation.topic, Pagination(after = date))
)
)

assertEquals(4, messages.size)
}

@Test
fun testImportV1ConversationFromJS() {
val jsExportJSONData =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,12 @@ class FakeApiClient : ApiClient {
}

override suspend fun batchQuery(requests: List<MessageApiOuterClass.QueryRequest>): MessageApiOuterClass.BatchQueryResponse {
val response = query(requests.first().getContentTopics(0))
val responses = requests.map {
query(it.getContentTopics(0), Pagination(after = Date(it.startTimeNs)))
}

return MessageApiOuterClass.BatchQueryResponse.newBuilder().also {
it.addResponses(response)
it.addAllResponses(responses)
}.build()
}

Expand All @@ -142,12 +144,14 @@ class FakeApiClient : ApiClient {

val startAt = pagination?.before
if (startAt != null) {
result = result.filter { it.timestampNs < startAt.time * 1_000_000 }
result = result.filter { it.timestampNs < startAt.time }
.sortedBy { it.timestampNs }.toMutableList()
}
val endAt = pagination?.after
if (endAt != null) {
result = result.filter { it.timestampNs > endAt.time * 1_000_000 }
result = result.filter {
it.timestampNs > endAt.time
}
.sortedBy { it.timestampNs }.toMutableList()
}
val limit = pagination?.limit
Expand Down Expand Up @@ -187,7 +191,11 @@ class FakeApiClient : ApiClient {
}
}

data class Fixtures(val aliceAccount: PrivateKeyBuilder, val bobAccount: PrivateKeyBuilder, val steveAccount: PrivateKeyBuilder) {
data class Fixtures(
val aliceAccount: PrivateKeyBuilder,
val bobAccount: PrivateKeyBuilder,
val steveAccount: PrivateKeyBuilder,
) {
var fakeApiClient: FakeApiClient = FakeApiClient()
var alice: PrivateKey = aliceAccount.getPrivateKey()
var aliceClient: Client = Client().create(account = aliceAccount, apiClient = fakeApiClient)
Expand All @@ -196,7 +204,11 @@ data class Fixtures(val aliceAccount: PrivateKeyBuilder, val bobAccount: Private
var steve: PrivateKey = steveAccount.getPrivateKey()
var steveClient: Client = Client().create(account = steveAccount, apiClient = fakeApiClient)

constructor() : this(aliceAccount = PrivateKeyBuilder(), bobAccount = PrivateKeyBuilder(), steveAccount = PrivateKeyBuilder())
constructor() : this(
aliceAccount = PrivateKeyBuilder(),
bobAccount = PrivateKeyBuilder(),
steveAccount = PrivateKeyBuilder()
)

fun publishLegacyContact(client: Client) {
val contactBundle = ContactBundle.newBuilder().also { builder ->
Expand Down
10 changes: 3 additions & 7 deletions library/src/main/java/org/xmtp/android/library/Conversations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -285,14 +285,10 @@ data class Conversations(
}

fun listBatchMessages(
topics: List<String>,
limit: Int? = null,
before: Date? = null,
after: Date? = null,
topics: List<Pair<String, Pagination?>>,
): List<DecodedMessage> {
val pagination = Pagination(limit = limit, before = before, after = after)
val requests = topics.map { topic ->
makeQueryRequest(topic = topic, pagination = pagination)
val requests = topics.map { (topic, page) ->
makeQueryRequest(topic = topic, pagination = page)
}

// The maximum number of requests permitted in a single batch call.
Expand Down

0 comments on commit 275714c

Please sign in to comment.